From 6cb495dee36d3099705c3a07a12de6ded4a30015 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 27 Apr 2015 18:13:34 +0200 Subject: [PATCH 01/29] make QMAKE_FRAMEWORK_VERSION work independently of TEMPLATE QMAKE_BUNDLE_DATA itself does as well, and it can refer to versioned resources. Change-Id: I3d9bf23c2ff81dbb1cd929f3f0e0ce1e67f3258a Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- qmake/generators/unix/unixmake2.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 50eb93cda94..9b9e54c4616 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -614,9 +614,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else if(!project->isEmpty("QMAKE_BUNDLE")) { - QString currentLink = destdir_r + "Versions/Current"; - QString currentLink_f = escapeDependencyPath(currentLink); - bundledFiles << currentLink << destdir_r + "$(TARGET)"; + bundledFiles << destdir_r + "$(TARGET)"; t << "\n\t" << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(DESTDIR)$(TARGET0)\n\t" << var("QMAKE_LINK_SHLIB_CMD") << "\n\t" @@ -624,10 +622,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << "-$(MOVE) $(TARGET) $(DESTDIR)$(TARGETD)\n\t" << mkdir_p_asstring("\"`dirname $(DESTDIR)$(TARGET0)`\"", false) << "\n\t" << varGlue("QMAKE_LN_SHLIB", "-", " ", - " Versions/Current/$(TARGET) $(DESTDIR)$(TARGET0)") << "\n\t" - << "-$(DEL_FILE) " << currentLink_f << "\n\t" - << varGlue("QMAKE_LN_SHLIB","-"," ", " " + project->first("QMAKE_FRAMEWORK_VERSION") + - ' ' + currentLink_f) << "\n\t"; + " Versions/Current/$(TARGET) $(DESTDIR)$(TARGET0)") << "\n\t"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; @@ -937,6 +932,17 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << mkdir_p_asstring(bundle_dir) << "\n\t" << "@$(SYMLINK) " << escapeFilePath(symIt.value()) << ' ' << bundle_dir_f << endl; } + if (!project->first("QMAKE_FRAMEWORK_VERSION").isEmpty()) { + QString currentLink = bundle_dir + "Versions/Current"; + QString currentLink_f = escapeDependencyPath(currentLink); + bundledFiles << currentLink; + alldeps << currentLink; + t << currentLink_f << ": $(MAKEFILE)\n\t" + << mkdir_p_asstring(bundle_dir + "Versions") << "\n\t" + << "@-$(DEL_FILE) " << currentLink_f << "\n\t" + << "@$(SYMLINK) " << project->first("QMAKE_FRAMEWORK_VERSION") + << ' ' << currentLink_f << endl; + } } t << endl << "all: " << deps From 0823e3f746161da030d24797a9f17c54f6fd763e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 27 Apr 2015 18:20:04 +0200 Subject: [PATCH 02/29] make headers-only modules work for framework builds Change-Id: I00125883335c5b8cc556b4e4c964e11c55aa989b Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_module.prf | 9 ++++++++- mkspecs/features/qt_module_pris.prf | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index afa20a9ab1e..66a7598597d 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -103,7 +103,14 @@ mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) { # Set the CFBundleIdentifier prefix for Qt frameworks QMAKE_TARGET_BUNDLE_PREFIX = org.qt-project #QMAKE_FRAMEWORK_VERSION = 4.0 - CONFIG += lib_bundle sliced_bundle qt_framework + CONFIG += sliced_bundle qt_framework + qt_no_install_library { + CONFIG += bundle + QMAKE_BUNDLE_EXTENSION = .framework + QMAKE_INFO_PLIST = $$QMAKESPEC/Info.plist.lib + } else { + CONFIG += lib_bundle + } CONFIG -= qt_install_headers #no need to install these as well !debug_and_release|!build_all|CONFIG(release, debug|release) { FRAMEWORK_HEADERS.version = Versions diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf index 46971ba604b..4ce03f43272 100644 --- a/mkspecs/features/qt_module_pris.prf +++ b/mkspecs/features/qt_module_pris.prf @@ -62,14 +62,14 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri module_rundep = "QT.$${MODULE_ID}.run_depends = $$replace(QT_PRIVATE, -private$, _private)" else: \ module_rundep = - equals(TEMPLATE, aux): \ - module_build_type = no_link - else:static: \ + static: \ module_build_type = staticlib else:mac:contains(QT_CONFIG, qt_framework): \ module_build_type = lib_bundle else: \ module_build_type = + equals(TEMPLATE, aux): \ + module_build_type += no_link internal_module: \ module_build_type += internal_module ltcg: \ From 39683b2980189bebcb35955eaa6aa0ae7cd353a7 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 24 Apr 2015 15:53:01 +0300 Subject: [PATCH 03/29] QSystemTrayIcon: Fix the placement of title and message in a balloon Swap title and message parameters in the QBalloonTip::showBalloon() call. It was wrong in f277c074675389eba0b27f2ccadddd98869fdfbb on xcb platform. Task-number: QTBUG-43428 Change-Id: I18e354703d9fa9c196b2789e6df263debdb7ce06 Reviewed-by: Shawn Rutledge --- src/widgets/util/qsystemtrayicon_x11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp index 2b153d53d97..4060655d450 100644 --- a/src/widgets/util/qsystemtrayicon_x11.cpp +++ b/src/widgets/util/qsystemtrayicon_x11.cpp @@ -372,7 +372,7 @@ void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString } if (!sys) return; - QBalloonTip::showBalloon(icon, message, title, sys->systemTrayIcon(), + QBalloonTip::showBalloon(icon, title, message, sys->systemTrayIcon(), sys->globalGeometry().center(), msecs); } From 84b739158d5fdc356e5c6c963ba740fd081db82e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 27 Apr 2015 10:32:32 +0200 Subject: [PATCH 04/29] QIODevice: fix data loss when reading large amounts from sequential devices In certain situations, when reading a large amount of data from sequential devices with QIODevice::readAll(), content was lost when passing a qint64 value > QByteArray::MaxSize into QByteArray::resize(), which takes an int. The result of the conversion to int is either negative or calculated mod 2^32. In any case, it will at some point be < QByteArray::size(), which prompts QByteArray to truncate, losing already-read content. Fix by adding an explicit size check before calling QByteArray::resize(). This shows once more that an API that uses int for sizes is dangerous. Esp. on 64-bit platforms. Change-Id: I30fbfad0bf37476c34141b6f3786e7e0fc8e1e74 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qiodevice.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 47484ad5968..e73a200fb4c 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -989,6 +989,10 @@ QByteArray QIODevice::readAll() // Size is unknown, read incrementally. qint64 readResult; do { + if (quint64(readBytes) + QIODEVICE_BUFFERSIZE > QByteArray::MaxSize) { + // If resize would fail, don't read more, return what we have. + break; + } result.resize(readBytes + QIODEVICE_BUFFERSIZE); readResult = read(result.data() + readBytes, QIODEVICE_BUFFERSIZE); if (readResult > 0 || readBytes == 0) From 1576f62eaf962aaaaba83337284d23c732bfb52b Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Fri, 10 Apr 2015 11:25:02 +0200 Subject: [PATCH 05/29] Tests: Use blacklist for failing tst_qfilesystemwatcher tests Remove the insignificant_tests CONFIG option in favor of a BLACKLIST file. The tests blacklisted have been found using CI builds logs. Change-Id: I34374ed7269f941c330c65d97fe083c83d3df461 Task-number: QTBUG-33574 Task-number: QTBUG-30943 Reviewed-by: Friedemann Kleint --- tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST | 8 ++++++++ .../corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST diff --git a/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST new file mode 100644 index 00000000000..3ac0b9dff45 --- /dev/null +++ b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST @@ -0,0 +1,8 @@ +# QTBUG-33574 QTBUG-30943 +[signalsEmittedAfterFileMoved] +windows 32bit msvc-2010 +windows 64bit msvc +[watchFileAndItsDirectory:native backend-testfile] +osx +[watchFileAndItsDirectory:native backend-specialchars] +osx diff --git a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro index 318e49a1130..1faa089c6e0 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro +++ b/tests/auto/corelib/io/qfilesystemwatcher/qfilesystemwatcher.pro @@ -3,5 +3,3 @@ TARGET = tst_qfilesystemwatcher QT = core testlib SOURCES = tst_qfilesystemwatcher.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 - -CONFIG += insignificant_test # QTBUG-33574 From f15d6c3fa910d5200e245fe15ae9932f4b4eca78 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 24 Apr 2015 16:04:14 +0200 Subject: [PATCH 06/29] Preserve QImage metadata in image transforms Some QImage methods were not preserving image metadata, or only preserving some of it. This adds the missing parts and adds a test for metadata. Change-Id: Ib5892a23e49dfde5ea26074d3deaa887fa930c6b Reviewed-by: Gunnar Sletta --- src/gui/image/qimage.cpp | 58 ++++++++++------------ src/gui/image/qimage.h | 1 + tests/auto/gui/image/qimage/tst_qimage.cpp | 36 ++++++++++++++ 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index f09e73f2143..7b558bf4dd5 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1087,6 +1087,15 @@ void QImage::detach() } +static void copyMetadata(QImageData *dst, const QImageData *src) +{ + // Doesn't copy colortable and alpha_clut, or offset. + dst->dpmx = src->dpmx; + dst->dpmy = src->dpmy; + dst->devicePixelRatio = src->devicePixelRatio; + dst->text = src->text; +} + /*! \fn QImage QImage::copy(int x, int y, int width, int height) const \overload @@ -1136,12 +1145,9 @@ QImage QImage::copy(const QRect& r) const } else memcpy(image.bits(), bits(), d->nbytes); image.d->colortable = d->colortable; - image.d->dpmx = d->dpmx; - image.d->dpmy = d->dpmy; - image.d->devicePixelRatio = d->devicePixelRatio; image.d->offset = d->offset; image.d->has_alpha_clut = d->has_alpha_clut; - image.d->text = d->text; + copyMetadata(image.d, d); return image; } @@ -1227,12 +1233,9 @@ QImage QImage::copy(const QRect& r) const } } - image.d->dpmx = dotsPerMeterX(); - image.d->dpmy = dotsPerMeterY(); - image.d->devicePixelRatio = devicePixelRatio(); + copyMetadata(image.d, d); image.d->offset = offset(); image.d->has_alpha_clut = d->has_alpha_clut; - image.d->text = d->text; return image; } @@ -1983,11 +1986,8 @@ QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags fl QIMAGE_SANITYCHECK_MEMORY(image); - image.setDotsPerMeterY(dotsPerMeterY()); - image.setDotsPerMeterX(dotsPerMeterX()); - image.setDevicePixelRatio(devicePixelRatio()); - - image.d->text = d->text; + image.d->offset = offset(); + copyMetadata(image.d, d); converter(image.d, d, flags); return image; @@ -2112,9 +2112,9 @@ QImage QImage::convertToFormat(Format format, const QVector &colorTable, Q QImage image(d->width, d->height, format); QIMAGE_SANITYCHECK_MEMORY(image); - image.setDevicePixelRatio(devicePixelRatio()); - image.d->text = d->text; + image.d->offset = offset(); + copyMetadata(image.d, d); converter(image.d, d, flags); return image; @@ -2952,9 +2952,7 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const result.d->colortable = d->colortable; result.d->has_alpha_clut = d->has_alpha_clut; - result.d->devicePixelRatio = d->devicePixelRatio; - result.d->dpmx = d->dpmx; - result.d->dpmy = d->dpmy; + copyMetadata(result.d, d); do_mirror(result.d, d, horizontal, vertical); @@ -3103,6 +3101,7 @@ QImage QImage::rgbSwapped_helper() const rgbSwapped_generic(d->width, d->height, this, &res, &qPixelLayouts[d->format]); break; } + copyMetadata(res.d, d); return res; } @@ -4254,8 +4253,8 @@ int QImage::bitPlaneCount() const return bpc; } -static QImage smoothScaled(const QImage &source, int w, int h) { - QImage src = source; +QImage QImage::smoothScaled(int w, int h) const { + QImage src = *this; switch (src.format()) { case QImage::Format_RGB32: case QImage::Format_ARGB32_Premultiplied: @@ -4270,11 +4269,11 @@ static QImage smoothScaled(const QImage &source, int w, int h) { else src = src.convertToFormat(QImage::Format_RGB32); } - - return qSmoothScaleImage(src, w, h); + src = qSmoothScaleImage(src, w, h); + copyMetadata(src.d, d); + return src; } - static QImage rotated90(const QImage &image) { QImage out(image.height(), image.width(), image.format()); if (image.colorCount() > 0) @@ -4475,13 +4474,13 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode // Make use of the optimized algorithm when we're scaling if (scale_xform && mode == Qt::SmoothTransformation) { if (mat.m11() < 0.0F && mat.m22() < 0.0F) { // horizontal/vertical flip - return smoothScaled(mirrored(true, true), wd, hd); + return smoothScaled(wd, hd).mirrored(true, true); } else if (mat.m11() < 0.0F) { // horizontal flip - return smoothScaled(mirrored(true, false), wd, hd); + return smoothScaled(wd, hd).mirrored(true, false); } else if (mat.m22() < 0.0F) { // vertical flip - return smoothScaled(mirrored(false, true), wd, hd); + return smoothScaled(wd, hd).mirrored(false, true); } else { // no flipping - return smoothScaled(*this, wd, hd); + return smoothScaled(wd, hd); } } @@ -4533,9 +4532,6 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode dImage.d->has_alpha_clut = d->has_alpha_clut | complex_xform; } - dImage.d->dpmx = dotsPerMeterX(); - dImage.d->dpmy = dotsPerMeterY(); - // initizialize the data if (d->format == QImage::Format_Indexed8) { if (dImage.d->colortable.size() < 256) { @@ -4573,8 +4569,8 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode int dbpl = dImage.bytesPerLine(); qt_xForm_helper(mat, 0, type, bpp, dImage.bits(), dbpl, 0, hd, sptr, sbpl, ws, hs); } + copyMetadata(dImage.d, d); - dImage.d->devicePixelRatio = devicePixelRatio(); return dImage; } diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 4ce99b9ab15..99044bd4e3f 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -328,6 +328,7 @@ protected: void rgbSwapped_inplace(); QImage convertToFormat_helper(Format format, Qt::ImageConversionFlags flags) const; bool convertToFormat_inplace(Format format, Qt::ImageConversionFlags flags); + QImage smoothScaled(int w, int h) const; private: friend class QWSOnScreenSurface; diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 5691a654d75..51e4c6233ee 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -184,6 +184,8 @@ private slots: void devicePixelRatio(); + void metadataPassthrough(); + private: const QString m_prefix; }; @@ -2827,5 +2829,39 @@ void tst_QImage::devicePixelRatio() QCOMPARE(b.devicePixelRatio(), qreal(1.0)); } +void tst_QImage::metadataPassthrough() +{ + QImage a(64, 64, QImage::Format_ARGB32); + a.fill(Qt::white); + a.setText(QStringLiteral("Test"), QStringLiteral("Text")); + a.setDotsPerMeterX(100); + a.setDotsPerMeterY(80); + a.setDevicePixelRatio(2.0); + + QImage scaled = a.scaled(QSize(32, 32), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + QCOMPARE(scaled.text(QStringLiteral("Test")), a.text(QStringLiteral("Test"))); + QCOMPARE(scaled.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(scaled.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(scaled.devicePixelRatio(), a.devicePixelRatio()); + + scaled = a.scaled(QSize(128, 128), Qt::IgnoreAspectRatio, Qt::FastTransformation); + QCOMPARE(scaled.text(QStringLiteral("Test")), a.text(QStringLiteral("Test"))); + QCOMPARE(scaled.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(scaled.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(scaled.devicePixelRatio(), a.devicePixelRatio()); + + QImage mirrored = a.mirrored(); + QCOMPARE(mirrored.text(QStringLiteral("Test")), a.text(QStringLiteral("Test"))); + QCOMPARE(mirrored.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(mirrored.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(mirrored.devicePixelRatio(), a.devicePixelRatio()); + + QImage swapped = a.rgbSwapped(); + QCOMPARE(swapped.text(QStringLiteral("Test")), a.text(QStringLiteral("Test"))); + QCOMPARE(swapped.dotsPerMeterX(), a.dotsPerMeterX()); + QCOMPARE(swapped.dotsPerMeterY(), a.dotsPerMeterY()); + QCOMPARE(swapped.devicePixelRatio(), a.devicePixelRatio()); +} + QTEST_GUILESS_MAIN(tst_QImage) #include "tst_qimage.moc" From 0abf5ec7c4e035f2d37b45cc2da583df829ec0d0 Mon Sep 17 00:00:00 2001 From: Marko Kangas Date: Thu, 16 Apr 2015 16:11:06 +0300 Subject: [PATCH 07/29] Add support to set text/uri-list mimedata via setData() Fixed issue that text/uri-list mimedata got from QMimeData::data() was corrupted after setting it back via QMimeData::setData() Change-Id: I2377523a9286519402ab9127ed7f3fa66e39a679 Task-number: QTBUG-45486 Reviewed-by: David Faure --- src/corelib/kernel/qmimedata.cpp | 17 ++++++++++++++++- .../corelib/kernel/qmimedata/tst_qmimedata.cpp | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp index 0753faf4695..3e9cdac966e 100644 --- a/src/corelib/kernel/qmimedata.cpp +++ b/src/corelib/kernel/qmimedata.cpp @@ -566,7 +566,22 @@ QByteArray QMimeData::data(const QString &mimeType) const void QMimeData::setData(const QString &mimeType, const QByteArray &data) { Q_D(QMimeData); - d->setData(mimeType, QVariant(data)); + + if (mimeType == QLatin1String("text/uri-list")) { + QByteArray ba = data; + if (ba.endsWith('\0')) + ba.chop(1); + QList urls = ba.split('\n'); + QList list; + for (int i = 0; i < urls.size(); ++i) { + QByteArray ba = urls.at(i).trimmed(); + if (!ba.isEmpty()) + list.append(QUrl::fromEncoded(ba)); + } + d->setData(mimeType, list); + } else { + d->setData(mimeType, QVariant(data)); + } } /*! diff --git a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp index 3886051fdca..01bf16c2950 100644 --- a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp +++ b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp @@ -297,9 +297,16 @@ void tst_QMimeData::setText() const QVERIFY(mimeData.hasText() == false); } +// Publish retrieveData for verifying content validity +class TstMetaData : public QMimeData +{ +public: + using QMimeData::retrieveData; +}; + void tst_QMimeData::setUrls() const { - QMimeData mimeData; + TstMetaData mimeData; QList shortUrlList; QList longUrlList; @@ -321,6 +328,14 @@ void tst_QMimeData::setUrls() const QCOMPARE(mimeData.urls(), longUrlList); QCOMPARE(mimeData.text(), QString("http://qt-project.org\nhttp://www.google.com\n")); + // test and verify that setData doesn't corrupt url content + foreach (const QString &format, mimeData.formats()) { + QVariant before = mimeData.retrieveData(format, QVariant::ByteArray); + mimeData.setData(format, mimeData.data(format)); + QVariant after = mimeData.retrieveData(format, QVariant::ByteArray); + QCOMPARE(after, before); + } + // clear, verify mimeData.clear(); QCOMPARE(mimeData.hasUrls(), false); From fc51e86ca444e713586f31ab0e0d0e26144bbfa7 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 20 Mar 2015 11:17:55 +0100 Subject: [PATCH 08/29] QStateMachine: optimize conflict calculation. Done by using in-place removal from the list of transitions using iterators. Change-Id: I6dced4b214b49b3dcd3ba19ca4cd81a601f81bb6 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine.cpp | 30 ++++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index dd0ba9260e1..f02e27330d9 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -483,6 +483,8 @@ function removeConflictingTransitions(enabledTransitions): filteredTransitions.add(t1) return filteredTransitions + +Note: the implementation below does not build the transitionsToRemove, but removes them in-place. */ void QStateMachinePrivate::removeConflictingTransitions(QList &enabledTransitions) { @@ -492,24 +494,36 @@ void QStateMachinePrivate::removeConflictingTransitions(QList transitionsToRemove; QSet exitSetT1 = computeExitSet_Unordered(QList() << t1); - foreach (QAbstractTransition *t2, filteredTransitions) { + QList::iterator t2It = filteredTransitions.begin(); + while (t2It != filteredTransitions.end()) { + QAbstractTransition *t2 = *t2It; + if (t1 == t2) { + // Special case: someone added the same transition object to a state twice. In this + // case, t2 (which is already in the list) "preempts" t1. + t1Preempted = true; + break; + } + QSet exitSetT2 = computeExitSet_Unordered(QList() << t2); - if (!exitSetT1.intersect(exitSetT2).isEmpty()) { + if (exitSetT1.intersect(exitSetT2).isEmpty()) { + // No conflict, no cry. Next patient please. + ++t2It; + } else { + // Houston, we have a conflict. Check which transition can be removed. if (isDescendant(t1->sourceState(), t2->sourceState())) { - transitionsToRemove.append(t2); + // t1 preempts t2, so we can remove t2 + t2It = filteredTransitions.erase(t2It); } else { + // t2 preempts t1, so there's no use in looking further and we don't need to add + // t1 to the list. t1Preempted = true; break; } } } - if (!t1Preempted) { - foreach (QAbstractTransition *t3, transitionsToRemove) - filteredTransitions.removeAll(t3); + if (!t1Preempted) filteredTransitions.append(t1); - } } enabledTransitions = filteredTransitions; From 7f8da2179b7542375d9cf472b74bb8c2b83435f1 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 27 Apr 2015 14:12:34 +0200 Subject: [PATCH 09/29] Convert opaque indexed images over RGB32 There is no reason to use the more expensive ARGB32 conversions when there is no alpha channel involved. Change-Id: Ifcb325352b8c806ef755db385121a2939c5825b2 Reviewed-by: Gunnar Sletta --- src/gui/image/qimage.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 7b558bf4dd5..1bbbc3e1f28 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1993,9 +1993,12 @@ QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags fl return image; } - // Convert indexed formats over ARGB32 to the final format. - Q_ASSERT(format != QImage::Format_ARGB32); - Q_ASSERT(d->format != QImage::Format_ARGB32); + // Convert indexed formats over ARGB32 or RGB32 to the final format. + Q_ASSERT(format != QImage::Format_ARGB32 && format != QImage::Format_RGB32); + Q_ASSERT(d->format != QImage::Format_ARGB32 && d->format != QImage::Format_RGB32); + + if (!hasAlphaChannel()) + return convertToFormat(Format_RGB32, flags).convertToFormat(format, flags); return convertToFormat(Format_ARGB32, flags).convertToFormat(format, flags); } @@ -4612,8 +4615,7 @@ bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFla if (ref.load() > 1 || ro_data) return false; - const InPlace_Image_Converter *const converterPtr = &qimage_inplace_converter_map[format][newFormat]; - InPlace_Image_Converter converter = *converterPtr; + InPlace_Image_Converter converter = qimage_inplace_converter_map[format][newFormat]; if (converter) return converter(this, flags); else if (format > QImage::Format_Indexed8 && newFormat > QImage::Format_Indexed8 && !qimage_converter_map[format][newFormat]) From 2596f95b3b2a1be31b13af1dc9a43198b6eca5bc Mon Sep 17 00:00:00 2001 From: Katja Marttila Date: Tue, 3 Mar 2015 12:23:29 +0200 Subject: [PATCH 10/29] Fix QTreeView ending up in wrong state when drag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed state in MouseRelease so that QTreeView does not end up in wrong state if drag is started but not completed. Task-number: QTBUG-44773 Change-Id: I0b665d2944f2b696bc4b7e79689d110aefa3f194 Reviewed-by: Friedemann Kleint Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qtreeview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 188a503d107..43db43fcd4e 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1913,7 +1913,7 @@ void QTreeView::mouseReleaseEvent(QMouseEvent *event) if (d->itemDecorationAt(event->pos()) == -1) { QAbstractItemView::mouseReleaseEvent(event); } else { - if (state() == QAbstractItemView::DragSelectingState) + if (state() == QAbstractItemView::DragSelectingState || state() == QAbstractItemView::DraggingState) setState(QAbstractItemView::NoState); if (style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, 0, this) == QEvent::MouseButtonRelease) d->expandOrCollapseItemAtPos(event->pos()); From 631eb12dd25b50389535947f305f2111550b9a69 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 27 Apr 2015 23:32:26 +0200 Subject: [PATCH 11/29] The qpluginloader machtest needs Q_AUTOTEST_EXPORT Doing a build on OS X without -developer-build fails. Change-Id: I49c178ab2428177d9dd94f84620595a4bc132244 Reviewed-by: Simon Hausmann --- tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro index f5d06b3de95..5c6c56e3896 100644 --- a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro +++ b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro @@ -5,7 +5,7 @@ SUBDIRS = lib \ theplugin \ tst !android: !win32: !mac: SUBDIRS += almostplugin -macx-*: SUBDIRS += machtest +macx-*: contains(QT_CONFIG, private_tests): SUBDIRS += machtest TARGET = tst_qpluginloader # no special install rule for subdir From fe086ddb9e4640489595a4c12aef6a27b989ed70 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 21 Apr 2015 18:54:55 +0300 Subject: [PATCH 12/29] xcb: Fix updating physical screen size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X server may return an empty physical screen size, for example on VNC, Xephyr or some not very well supported hardware. In this case it's possible to use the size of the virtual desktop, but until now it was done only in the QXcbScreen constructor. Move it to QXcbScreen::updateGeometry() and calculate physical screen size using the DPI of the virtual desktop. Task-number: QTBUG-45564 Change-Id: I6b757818a2fcefdd7b2c0aa31b840a88d625d6ae Reviewed-by: Daniel Vrátil Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/xcb/qxcbscreen.cpp | 25 +++++++++++++++++------- src/plugins/platforms/xcb/qxcbscreen.h | 1 + 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index a0d6d88d115..c14ec0bb3f7 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -108,10 +108,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe } const int dpr = int(devicePixelRatio()); - // On VNC, it can be that physical size is unknown while - // virtual size is known (probably back-calculated from DPI and resolution) - if (m_sizeMillimeters.isEmpty()) - m_sizeMillimeters = m_virtualSizeMillimeters; if (m_geometry.isEmpty()) { m_geometry = QRect(QPoint(), m_virtualSize/dpr); m_nativeGeometry = QRect(QPoint(), m_virtualSize); @@ -353,6 +349,12 @@ QImage::Format QXcbScreen::format() const return QImage::Format_RGB32; } +QDpi QXcbScreen::virtualDpi() const +{ + return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(), + Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); +} + QDpi QXcbScreen::logicalDpi() const { static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI"); @@ -363,8 +365,7 @@ QDpi QXcbScreen::logicalDpi() const int primaryDpr = int(connection()->screens().at(0)->devicePixelRatio()); return QDpi(m_forcedDpi/primaryDpr, m_forcedDpi/primaryDpr); } - return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(), - Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); + return virtualDpi(); } @@ -415,7 +416,6 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan return; m_rotation = change_event->rotation; - updateGeometry(change_event->timestamp); switch (m_rotation) { case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal m_orientation = Qt::LandscapeOrientation; @@ -451,6 +451,8 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan case XCB_RANDR_ROTATION_REFLECT_Y: break; } + updateGeometry(change_event->timestamp); + QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation); @@ -504,6 +506,15 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation) break; } + // It can be that physical size is unknown while virtual size + // is known (probably back-calculated from DPI and resolution), + // e.g. on VNC or with some hardware. + if (m_sizeMillimeters.isEmpty()) { + QDpi dpi = virtualDpi(); + m_sizeMillimeters = QSizeF(Q_MM_PER_INCH * xGeometry.width() / dpi.first, + Q_MM_PER_INCH * xGeometry.width() / dpi.second); + } + xcb_get_property_reply_t * workArea = xcb_get_property_reply(xcb_connection(), xcb_get_property_unchecked(xcb_connection(), false, screen()->root, diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index a29efc1e799..ec05e3bb25c 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -94,6 +94,7 @@ public: QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_sizeMillimeters; } QSize virtualSize() const { return m_virtualSize; } QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; } + QDpi virtualDpi() const; QDpi logicalDpi() const Q_DECL_OVERRIDE; qreal devicePixelRatio() const Q_DECL_OVERRIDE; QPlatformCursor *cursor() const Q_DECL_OVERRIDE; From 52ddfb36c80f1f0cba4e90d40b43c426687fac41 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 27 Apr 2015 12:10:12 +0200 Subject: [PATCH 13/29] Fix two errors in RGB30 conversions The one converters from RGB30 was misplaced in the method table, and the unpremultiplication from A2RGB30 to RGB30 had an underflow mistake when alpha was 2. Change-Id: I92c11ede28611a3dbdce72aca1898845c120c209 Reviewed-by: Gunnar Sletta --- src/gui/image/qimage_conversions.cpp | 6 +++--- tests/auto/gui/image/qimage/tst_qimage.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 28e3a48689c..e1be0322155 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -557,7 +557,7 @@ static inline uint qUnpremultiplyRgb30(uint rgb30) } case 2: { uint rgb = rgb30 & 0x3fffffff; - rgb += rgb >> 1; + rgb += (rgb >> 1) & 0x5ff7fdff; return (a << 30) | rgb; } case 3: @@ -2348,9 +2348,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_BGR30_to_RGB30, - convert_BGR30_to_RGB30, 0, + convert_BGR30_to_RGB30, + convert_BGR30_to_RGB30, 0, convert_passthrough, 0, 0 diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 51e4c6233ee..266230de387 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -183,6 +183,7 @@ private slots: void cleanupFunctions(); void devicePixelRatio(); + void rgb30Unpremul(); void metadataPassthrough(); @@ -2829,6 +2830,20 @@ void tst_QImage::devicePixelRatio() QCOMPARE(b.devicePixelRatio(), qreal(1.0)); } +void tst_QImage::rgb30Unpremul() +{ + QImage a(3, 1, QImage::Format_A2RGB30_Premultiplied); + ((uint*)a.bits())[0] = (3U << 30) | (128 << 20) | (256 << 10) | 512; + ((uint*)a.bits())[1] = (2U << 30) | (131 << 20) | (259 << 10) | 515; + ((uint*)a.bits())[2] = (1U << 30) | ( 67 << 20) | (131 << 10) | 259; + + QImage b = a.convertToFormat(QImage::Format_RGB30); + const uint* bbits = (const uint*)b.bits(); + QCOMPARE(bbits[0], (3U << 30) | (128 << 20) | (256 << 10) | 512); + QCOMPARE(bbits[1], (3U << 30) | (196 << 20) | (388 << 10) | 772); + QCOMPARE(bbits[2], (3U << 30) | (201 << 20) | (393 << 10) | 777); +} + void tst_QImage::metadataPassthrough() { QImage a(64, 64, QImage::Format_ARGB32); From 4e88f1aaea94ae021b31d914d54a35ae89125e15 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 Apr 2015 14:47:46 +0200 Subject: [PATCH 14/29] Windows QPA plugin: Fix debug formatting. - Introduce QDebugStateSaver for all debug operators. - Remove the "Flags=" from enumerations since their type is now output by default. - Added some spaces since the previous formatting relied on space=true as a result of some debug operators erroneously returning debug.space(), which is now fixed in qtbase. - Fixed formatting, added noquote() where necessary, added some newlines, used stream modifiers instead of QString::number(n, 16) to output hex numbers. - Fix indentation. Change-Id: I64123a4262916e21448cda2aa61ae1100f07291a Reviewed-by: Joerg Bornemann --- .../platforms/windows/qwindowsclipboard.cpp | 15 ++-- .../platforms/windows/qwindowscontext.cpp | 4 +- .../windows/qwindowsdialoghelpers.cpp | 7 +- .../windows/qwindowsfontdatabase.cpp | 12 +-- .../platforms/windows/qwindowsglcontext.cpp | 71 ++++++++-------- .../platforms/windows/qwindowsintegration.cpp | 11 ++- .../platforms/windows/qwindowsscreen.cpp | 24 +++--- .../platforms/windows/qwindowswindow.cpp | 84 ++++++++++--------- 8 files changed, 124 insertions(+), 104 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index bfcc9e9bcef..4cea845c36e 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -71,22 +71,23 @@ static const char formatTextHtmlC[] = "text/html"; QDebug operator<<(QDebug d, const QMimeData &m) { - QDebug nospace = d.nospace(); + QDebugStateSaver saver(d); + d.nospace(); const QStringList formats = m.formats(); - nospace << "QMimeData: " << formats.join(QStringLiteral(", ")) << '\n' + d << "QMimeData: " << formats.join(QStringLiteral(", ")) << '\n' << " Text=" << m.hasText() << " HTML=" << m.hasHtml() << " Color=" << m.hasColor() << " Image=" << m.hasImage() << " URLs=" << m.hasUrls() << '\n'; if (m.hasText()) - nospace << " Text: '" << m.text() << "'\n"; + d << " Text: '" << m.text() << "'\n"; if (m.hasHtml()) - nospace << " HTML: '" << m.html() << "'\n"; + d << " HTML: '" << m.html() << "'\n"; if (m.hasColor()) - nospace << " Color: " << qvariant_cast(m.colorData()) << '\n'; + d << " Color: " << qvariant_cast(m.colorData()) << '\n'; if (m.hasImage()) - nospace << " Image: " << qvariant_cast(m.imageData()).size() << '\n'; + d << " Image: " << qvariant_cast(m.imageData()).size() << '\n'; if (m.hasUrls()) - nospace << " URLs: " << m.urls() << '\n'; + d << " URLs: " << m.urls() << '\n'; return d; } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 7d7ea031a5b..a532e923977 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -566,8 +566,8 @@ QString QWindowsContext::registerWindowClass(QString cname, d->m_registeredWindowClassNames.insert(cname); qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << cname - << " style=0x" << QString::number(style, 16) - << " brush=" << brush << " icon=" << icon << " atom=" << atom; + << " style=0x" << hex << style << dec + << " brush=" << brush << " icon=" << icon << " atom=" << atom; return cname; } diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 3284795fc15..da0ba27e3a4 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -379,7 +379,12 @@ static inline QString guidToString(const GUID &g) } inline QDebug operator<<(QDebug d, const GUID &g) -{ d.nospace() << guidToString(g); return d; } +{ + QDebugStateSaver saver(d); + d.nospace(); + d << guidToString(g); + return d; +} // Return an allocated wchar_t array from a QString, reserve more memory if desired. static wchar_t *qStringToWCharArray(const QString &s, size_t reserveSize = 0) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 28fb3b6498e..a544b9d81e7 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -608,11 +608,13 @@ static inline bool initDirectWrite(QWindowsFontEngineData *d) QDebug operator<<(QDebug d, const QFontDef &def) { - d.nospace() << "Family=" << def.family << " Stylename=" << def.styleName - << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize - << " styleHint=" << def.styleHint << " weight=" << def.weight - << " stretch=" << def.stretch << " hintingPreference=" - << def.hintingPreference << ' '; + QDebugStateSaver saver(d); + d.nospace(); + d << "Family=" << def.family << " Stylename=" << def.styleName + << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize + << " styleHint=" << def.styleHint << " weight=" << def.weight + << " stretch=" << def.stretch << " hintingPreference=" + << def.hintingPreference; return d; } diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index d9eec9f6034..a7c14ed2acd 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -286,40 +286,41 @@ static inline void initPixelFormatDescriptor(PIXELFORMATDESCRIPTOR *d) QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd) { - QDebug nsp = d.nospace(); - nsp << "PIXELFORMATDESCRIPTOR " + QDebugStateSaver saver(d); + d.nospace(); + d << "PIXELFORMATDESCRIPTOR " << "dwFlags=" << hex << showbase << pd.dwFlags << dec << noshowbase; - if (pd.dwFlags & PFD_DRAW_TO_WINDOW) nsp << " PFD_DRAW_TO_WINDOW"; - if (pd.dwFlags & PFD_DRAW_TO_BITMAP) nsp << " PFD_DRAW_TO_BITMAP"; - if (pd.dwFlags & PFD_SUPPORT_GDI) nsp << " PFD_SUPPORT_GDI"; - if (pd.dwFlags & PFD_SUPPORT_OPENGL) nsp << " PFD_SUPPORT_OPENGL"; - if (pd.dwFlags & PFD_GENERIC_ACCELERATED) nsp << " PFD_GENERIC_ACCELERATED"; - if (pd.dwFlags & PFD_SUPPORT_DIRECTDRAW) nsp << " PFD_SUPPORT_DIRECTDRAW"; - if (pd.dwFlags & PFD_DIRECT3D_ACCELERATED) nsp << " PFD_DIRECT3D_ACCELERATED"; - if (pd.dwFlags & PFD_SUPPORT_COMPOSITION) nsp << " PFD_SUPPORT_COMPOSITION"; - if (pd.dwFlags & PFD_GENERIC_FORMAT) nsp << " PFD_GENERIC_FORMAT"; - if (pd.dwFlags & PFD_NEED_PALETTE) nsp << " PFD_NEED_PALETTE"; - if (pd.dwFlags & PFD_NEED_SYSTEM_PALETTE) nsp << " PFD_NEED_SYSTEM_PALETTE"; - if (pd.dwFlags & PFD_DOUBLEBUFFER) nsp << " PFD_DOUBLEBUFFER"; - if (pd.dwFlags & PFD_STEREO) nsp << " PFD_STEREO"; - if (pd.dwFlags & PFD_SWAP_LAYER_BUFFERS) nsp << " PFD_SWAP_LAYER_BUFFERS"; - if (hasGLOverlay(pd)) nsp << " overlay"; - nsp << " iPixelType=" << pd.iPixelType << " cColorBits=" << pd.cColorBits + if (pd.dwFlags & PFD_DRAW_TO_WINDOW) d << " PFD_DRAW_TO_WINDOW"; + if (pd.dwFlags & PFD_DRAW_TO_BITMAP) d << " PFD_DRAW_TO_BITMAP"; + if (pd.dwFlags & PFD_SUPPORT_GDI) d << " PFD_SUPPORT_GDI"; + if (pd.dwFlags & PFD_SUPPORT_OPENGL) d << " PFD_SUPPORT_OPENGL"; + if (pd.dwFlags & PFD_GENERIC_ACCELERATED) d << " PFD_GENERIC_ACCELERATED"; + if (pd.dwFlags & PFD_SUPPORT_DIRECTDRAW) d << " PFD_SUPPORT_DIRECTDRAW"; + if (pd.dwFlags & PFD_DIRECT3D_ACCELERATED) d << " PFD_DIRECT3D_ACCELERATED"; + if (pd.dwFlags & PFD_SUPPORT_COMPOSITION) d << " PFD_SUPPORT_COMPOSITION"; + if (pd.dwFlags & PFD_GENERIC_FORMAT) d << " PFD_GENERIC_FORMAT"; + if (pd.dwFlags & PFD_NEED_PALETTE) d << " PFD_NEED_PALETTE"; + if (pd.dwFlags & PFD_NEED_SYSTEM_PALETTE) d << " PFD_NEED_SYSTEM_PALETTE"; + if (pd.dwFlags & PFD_DOUBLEBUFFER) d << " PFD_DOUBLEBUFFER"; + if (pd.dwFlags & PFD_STEREO) d << " PFD_STEREO"; + if (pd.dwFlags & PFD_SWAP_LAYER_BUFFERS) d << " PFD_SWAP_LAYER_BUFFERS"; + if (hasGLOverlay(pd)) d << " overlay"; + d << " iPixelType=" << pd.iPixelType << " cColorBits=" << pd.cColorBits << " cRedBits=" << pd.cRedBits << " cRedShift=" << pd.cRedShift << " cGreenBits=" << pd.cGreenBits << " cGreenShift=" << pd.cGreenShift << " cBlueBits=" << pd.cBlueBits << " cBlueShift=" << pd.cBlueShift; - nsp << " cDepthBits=" << pd.cDepthBits; + d << " cDepthBits=" << pd.cDepthBits; if (pd.cStencilBits) - nsp << " cStencilBits=" << pd.cStencilBits; + d << " cStencilBits=" << pd.cStencilBits; if (pd.cAuxBuffers) - nsp << " cAuxBuffers=" << pd.cAuxBuffers; - nsp << " iLayerType=" << pd.iLayerType; + d << " cAuxBuffers=" << pd.cAuxBuffers; + d << " iLayerType=" << pd.iLayerType; if (pd.dwVisibleMask) - nsp << " dwVisibleMask=" << pd.dwVisibleMask; + d << " dwVisibleMask=" << pd.dwVisibleMask; if (pd.cAlphaBits) - nsp << " cAlphaBits=" << pd.cAlphaBits << " cAlphaShift=" << pd.cAlphaShift; + d << " cAlphaBits=" << pd.cAlphaBits << " cAlphaShift=" << pd.cAlphaShift; if (pd.cAccumBits) - nsp << " cAccumBits=" << pd.cAccumBits << " cAccumRedBits=" << pd.cAccumRedBits + d << " cAccumBits=" << pd.cAccumBits << " cAccumRedBits=" << pd.cAccumRedBits << " cAccumGreenBits=" << pd.cAccumGreenBits << " cAccumBlueBits=" << pd.cAccumBlueBits << " cAccumAlphaBits=" << pd.cAccumAlphaBits; return d; @@ -906,9 +907,10 @@ void QWindowsOpenGLContextFormat::apply(QSurfaceFormat *format) const QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &f) { - d.nospace() << "ContextFormat: v" << (f.version >> 8) << '.' - << (f.version & 0xFF) << " profile: " << f.profile - << " options: " << f.options; + QDebugStateSaver saver(d); + d.nospace(); + d << "ContextFormat: v" << (f.version >> 8) << '.' << (f.version & 0xFF) + << " profile: " << f.profile << " options: " << f.options; return d; } @@ -1018,16 +1020,17 @@ QOpenGLStaticContext *QOpenGLStaticContext::create(bool softwareRendering) QDebug operator<<(QDebug d, const QOpenGLStaticContext &s) { - QDebug nsp = d.nospace(); - nsp << "OpenGL: " << s.vendor << ',' << s.renderer << " default " + QDebugStateSaver saver(d); + d.nospace(); + d << "OpenGL: " << s.vendor << ',' << s.renderer << " default " << s.defaultFormat; if (s.extensions & QOpenGLStaticContext::SampleBuffers) - nsp << ",SampleBuffers"; + d << ",SampleBuffers"; if (s.hasExtensions()) - nsp << ", Extension-API present"; - nsp << "\nExtensions: " << (s.extensionNames.count(' ') + 1); + d << ", Extension-API present"; + d << "\nExtensions: " << (s.extensionNames.count(' ') + 1); if (QWindowsContext::verbose > 1) - nsp << s.extensionNames; + d << s.extensionNames; return d; } diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 1041ecf44d5..9b0f1262411 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -315,13 +315,12 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const QWindowsWindowData obtained = QWindowsWindowData::create(window, requested, window->title()); qCDebug(lcQpaWindows).nospace() - << __FUNCTION__ << '<' << window - << "\n Requested: " << requested.geometry << "frame incl.: " + << __FUNCTION__ << ' ' << window + << "\n Requested: " << requested.geometry << " frame incl.=" << QWindowsGeometryHint::positionIncludesFrame(window) - << " Flags=" << requested.flags - << "\n Obtained : " << obtained.geometry << " Margins "<< obtained.frame - << " Flags=" << obtained.flags - << " Handle=" << obtained.hwnd << '\n'; + << ' ' << requested.flags + << "\n Obtained : " << obtained.geometry << " margins=" << obtained.frame + << " handle=" << obtained.hwnd << ' ' << obtained.flags << '\n'; if (obtained.hwnd) { if (requested.flags != obtained.flags) diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 28e2aadf14b..7756c770013 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -173,20 +173,22 @@ static inline WindowsScreenDataList monitorData() static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) { - QDebug nospace = dbg.nospace(); - nospace << "Screen " << d.name << ' ' - << d.geometry.width() << 'x' << d.geometry.height() << '+' << d.geometry.x() << '+' << d.geometry.y() - << " avail: " - << d.availableGeometry.width() << 'x' << d.availableGeometry.height() << '+' << d.availableGeometry.x() << '+' << d.availableGeometry.y() - << " physical: " << d.physicalSizeMM.width() << 'x' << d.physicalSizeMM.height() - << " DPI: " << d.dpi.first << 'x' << d.dpi.second << " Depth: " << d.depth - << " Format: " << d.format; + QDebugStateSaver saver(dbg); + dbg.nospace(); + dbg.noquote(); + dbg << "Screen \"" << d.name << "\" " + << d.geometry.width() << 'x' << d.geometry.height() << '+' << d.geometry.x() << '+' << d.geometry.y() + << " avail: " + << d.availableGeometry.width() << 'x' << d.availableGeometry.height() << '+' << d.availableGeometry.x() << '+' << d.availableGeometry.y() + << " physical: " << d.physicalSizeMM.width() << 'x' << d.physicalSizeMM.height() + << " DPI: " << d.dpi.first << 'x' << d.dpi.second << " Depth: " << d.depth + << " Format: " << d.format; if (d.flags & QWindowsScreenData::PrimaryScreen) - nospace << " primary"; + dbg << " primary"; if (d.flags & QWindowsScreenData::VirtualDesktop) - nospace << " virtual desktop"; + dbg << " virtual desktop"; if (d.flags & QWindowsScreenData::LockScreen) - nospace << " lock screen"; + dbg << " lock screen"; return dbg; } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index b19510073a4..923040fd718 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -109,12 +109,13 @@ static QByteArray debugWinExStyle(DWORD exStyle) #ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO QDebug operator<<(QDebug d, const MINMAXINFO &i) { - d.nospace() << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ',' - << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x - << ',' << i.ptMaxPosition.y << " mintrack=" - << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y - << " maxtrack=" << i.ptMaxTrackSize.x << ',' - << i.ptMaxTrackSize.y; + QDebugStateSaver saver(d); + d.nospace(); + d << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ',' + << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x + << ',' << i.ptMaxPosition.y << " mintrack=" + << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y + << " maxtrack=" << i.ptMaxTrackSize.x << ',' << i.ptMaxTrackSize.y; return d; } #endif // !Q_OS_WINCE @@ -139,18 +140,20 @@ static inline RECT RECTfromQRect(const QRect &rect) QDebug operator<<(QDebug d, const RECT &r) { - d.nospace() << "RECT: left/top=" << r.left << ',' << r.top - << " right/bottom=" << r.right << ',' << r.bottom; + QDebugStateSaver saver(d); + d.nospace(); + d << "RECT: left/top=" << r.left << ',' << r.top + << " right/bottom=" << r.right << ',' << r.bottom; return d; } #ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_NCCALCSIZE QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p) { - qDebug().nospace() << "NCCALCSIZE_PARAMS " - << qrectFromRECT(p.rgrc[0]) - << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' - << qrectFromRECT(p.rgrc[2]); + QDebugStateSaver saver(d); + d.nospace(); + d << "NCCALCSIZE_PARAMS " << qrectFromRECT(p.rgrc[0]) + << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' << qrectFromRECT(p.rgrc[2]); return d; } #endif // !Q_OS_WINCE @@ -417,13 +420,18 @@ struct WindowCreationData QDebug operator<<(QDebug debug, const WindowCreationData &d) { - debug.nospace() << d.flags - << " topLevel=" << d.topLevel << " popup=" - << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop - << " embedded=" << d.embedded - << " tool=" << d.tool << " style=" << debugWinStyle(d.style) - << " exStyle=" << debugWinExStyle(d.exStyle) - << " parent=" << d.parentHandle; + QDebugStateSaver saver(debug); + debug.nospace(); + debug.noquote(); + debug << "WindowCreationData: " << d.flags + << "\n topLevel=" << d.topLevel; + if (d.parentHandle) + debug << " parent=" << d.parentHandle; + debug << " popup=" << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop + << " embedded=" << d.embedded << " tool=" << d.tool + << "\n style=" << debugWinStyle(d.style); + if (d.exStyle) + debug << "\n exStyle=" << debugWinExStyle(d.exStyle); return debug; } @@ -614,8 +622,8 @@ QWindowsWindowData QWindowsContext::instance()->setWindowCreationContext(context); qCDebug(lcQpaWindows).nospace() - << "CreateWindowEx: " << w << *this << " class=" <frameWidth << 'x' << context->frameHeight << '+' << context->frameX << '+' << context->frameY << " custom margins: " << context->customMargins; @@ -631,7 +639,7 @@ QWindowsWindowData #endif qCDebug(lcQpaWindows).nospace() << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: " - << context->obtainedGeometry << context->margins; + << context->obtainedGeometry << ' ' << context->margins; if (!result.hwnd) { qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__); @@ -732,9 +740,9 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle) qErrnoWarning("%s: AdjustWindowRectEx failed", __FUNCTION__); const QMargins result(qAbs(rect.left), qAbs(rect.top), qAbs(rect.right), qAbs(rect.bottom)); - qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style= 0x" - << QString::number(style, 16) << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result; - + qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style=" + << showbase << hex << style << " exStyle=" << exStyle << dec << noshowbase + << ' ' << rect << ' ' << result; return result; } @@ -853,12 +861,12 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, } qCDebug(lcQpaWindows).nospace() - << __FUNCTION__ << ' ' << w << geometry - << " pos incl. frame" << QWindowsGeometryHint::positionIncludesFrame(w) - << " frame: " << frameWidth << 'x' << frameHeight << '+' + << __FUNCTION__ << ' ' << w << ' ' << geometry + << " pos incl. frame=" << QWindowsGeometryHint::positionIncludesFrame(w) + << " frame=" << frameWidth << 'x' << frameHeight << '+' << frameX << '+' << frameY - << " min" << geometryHint.minimumSize << " max" << geometryHint.maximumSize - << " custom margins " << customMargins; + << " min=" << geometryHint.minimumSize << " max=" << geometryHint.maximumSize + << " custom margins=" << customMargins; } /*! @@ -1422,10 +1430,10 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const const QMargins margins = frameMarginsDp(); const QRect frameGeometry = rect + margins; - qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() - << " \n from " << geometry_sys() << " frame: " - << margins << " to " <' << __FUNCTION__ << window() + << "\n from " << geometry_sys() << " frame: " + << margins << " to " <("format"); - QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8; - QTest::newRow("Format_RGB32") << QImage::Format_RGB32; - QTest::newRow("Format_ARGB32") << QImage::Format_ARGB32; - QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied; - QTest::newRow("Format_RGB16") << QImage::Format_RGB16; - QTest::newRow("Format_ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied; - QTest::newRow("Format_ARGB6666_Premultiplied") << QImage::Format_ARGB6666_Premultiplied; - QTest::newRow("Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied; - QTest::newRow("Format_RGB666") << QImage::Format_RGB666; - QTest::newRow("Format_RGB555") << QImage::Format_RGB555; - QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied; - QTest::newRow("Format_RGB888") << QImage::Format_RGB888; - QTest::newRow("Format_RGB444") << QImage::Format_RGB444; - QTest::newRow("Format_RGBX8888") << QImage::Format_RGBX8888; - QTest::newRow("Format_RGBA8888_Premultiplied") << QImage::Format_RGBA8888_Premultiplied; - QTest::newRow("Format_A2BGR30_Premultiplied") << QImage::Format_A2BGR30_Premultiplied; - QTest::newRow("Format_RGB30") << QImage::Format_RGB30; + for (int i = QImage::Format_Indexed8; i < QImage::Format_Alpha8; ++i) { + QTest::newRow(qPrintable(formatToString(QImage::Format(i)))) << QImage::Format(i); + } } void tst_QImage::rgbSwapped() @@ -2398,23 +2449,18 @@ void tst_QImage::inplaceMirrored_data() QTest::addColumn("swap_vertical"); QTest::addColumn("swap_horizontal"); - QTest::newRow("Format_ARGB32, vertical") << QImage::Format_ARGB32 << true << false; - QTest::newRow("Format_RGB888, vertical") << QImage::Format_RGB888 << true << false; - QTest::newRow("Format_RGB16, vertical") << QImage::Format_RGB16 << true << false; - QTest::newRow("Format_Indexed8, vertical") << QImage::Format_Indexed8 << true << false; - QTest::newRow("Format_Mono, vertical") << QImage::Format_Mono << true << false; - - QTest::newRow("Format_ARGB32, horizontal") << QImage::Format_ARGB32 << false << true; - QTest::newRow("Format_RGB888, horizontal") << QImage::Format_RGB888 << false << true; - QTest::newRow("Format_RGB16, horizontal") << QImage::Format_RGB16 << false << true; - QTest::newRow("Format_Indexed8, horizontal") << QImage::Format_Indexed8 << false << true; - QTest::newRow("Format_Mono, horizontal") << QImage::Format_Mono << false << true; - - QTest::newRow("Format_ARGB32, horizontal+vertical") << QImage::Format_ARGB32 << true << true; - QTest::newRow("Format_RGB888, horizontal+vertical") << QImage::Format_RGB888 << true << true; - QTest::newRow("Format_RGB16, horizontal+vertical") << QImage::Format_RGB16 << true << true; - QTest::newRow("Format_Indexed8, horizontal+vertical") << QImage::Format_Indexed8 << true << true; - QTest::newRow("Format_Mono, horizontal+vertical") << QImage::Format_Mono << true << true; + for (int i = QImage::Format_Mono; i < QImage::NImageFormats; ++i) { + if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8) + continue; + if (i == QImage::Format_RGB444 || i == QImage::Format_ARGB4444_Premultiplied) + continue; + QTest::newRow(qPrintable(formatToString(QImage::Format(i)) + QStringLiteral(", vertical"))) + << QImage::Format(i) << true << false; + QTest::newRow(qPrintable(formatToString(QImage::Format(i)) + QStringLiteral(", horizontal"))) + << QImage::Format(i) << false << true; + QTest::newRow(qPrintable(formatToString(QImage::Format(i)) + QStringLiteral(", horizontal+vertical"))) + << QImage::Format(i) << true << true; + } } void tst_QImage::inplaceMirrored() @@ -2428,6 +2474,7 @@ void tst_QImage::inplaceMirrored() switch (format) { case QImage::Format_Mono: + case QImage::Format_MonoLSB: for (int i = 0; i < image.height(); ++i) { ushort* scanLine = (ushort*)image.scanLine(i); *scanLine = (i % 2) ? 0x0fffU : 0xf000U; @@ -2450,7 +2497,7 @@ void tst_QImage::inplaceMirrored() const uchar* originalPtr = image.constScanLine(0); QImage imageMirrored = std::move(image).mirrored(swap_horizontal, swap_vertical); - if (format != QImage::Format_Mono) { + if (format != QImage::Format_Mono && format != QImage::Format_MonoLSB) { for (int i = 0; i < imageMirrored.height(); ++i) { int mirroredI = swap_vertical ? (imageMirrored.height() - i - 1) : i; for (int j = 0; j < imageMirrored.width(); ++j) { @@ -2540,23 +2587,60 @@ void tst_QImage::inplaceRgbMirrored() #endif } -void tst_QImage::inplaceConversion_data() +void tst_QImage::genericRgbConversion_data() { QTest::addColumn("format"); QTest::addColumn("dest_format"); - QTest::newRow("Format_RGB32 -> RGB16") << QImage::Format_RGB32 << QImage::Format_RGB16; - QTest::newRow("Format_ARGB32 -> Format_RGBA8888") << QImage::Format_ARGB32 << QImage::Format_RGBA8888; - QTest::newRow("Format_RGB888 -> Format_ARGB6666_Premultiplied") << QImage::Format_RGB888 << QImage::Format_ARGB6666_Premultiplied; - QTest::newRow("Format_RGB16 -> Format_RGB555") << QImage::Format_RGB16 << QImage::Format_RGB555; - QTest::newRow("Format_RGB666 -> Format_RGB888") << QImage::Format_RGB666 << QImage::Format_RGB888; - QTest::newRow("Format_ARGB8565_Premultiplied, Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8565_Premultiplied << QImage::Format_ARGB8555_Premultiplied; - QTest::newRow("Format_ARGB4444_Premultiplied, Format_RGB444") << QImage::Format_ARGB4444_Premultiplied << QImage::Format_RGB444; - QTest::newRow("Format_RGBA8888 -> RGB16") << QImage::Format_RGBA8888 << QImage::Format_RGB16; - QTest::newRow("Format_RGBA8888_Premultiplied -> RGB16") << QImage::Format_RGBA8888_Premultiplied << QImage::Format_RGB16; + for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) { + for (int j = QImage::Format_RGB32; j < QImage::Format_Alpha8; ++j) { + if (i == j) + continue; + QString test = QString::fromLatin1("%1 -> %2").arg(formatToString(QImage::Format(i))).arg(formatToString(QImage::Format(j))); + QTest::newRow(qPrintable(test)) << QImage::Format(i) << QImage::Format(j); + } + } } -void tst_QImage::inplaceConversion() +void tst_QImage::genericRgbConversion() +{ + // Test that all RGB conversions work and maintain at least 4bit of color accuracy. + QFETCH(QImage::Format, format); + QFETCH(QImage::Format, dest_format); + + QImage image(16, 16, format); + + for (int i = 0; i < image.height(); ++i) + for (int j = 0; j < image.width(); ++j) + image.setPixel(j, i, qRgb(j*16, i*16, 0)); + + QImage imageConverted = image.convertToFormat(dest_format); + QCOMPARE(imageConverted.format(), dest_format); + for (int i = 0; i < imageConverted.height(); ++i) { + for (int j = 0; j < imageConverted.width(); ++j) { + QRgb convertedColor = imageConverted.pixel(j,i); + QCOMPARE(qRed(convertedColor) & 0xF0, j * 16); + QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16); + } + } +} + +void tst_QImage::inplaceRgbConversion_data() +{ + QTest::addColumn("format"); + QTest::addColumn("dest_format"); + + for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) { + for (int j = QImage::Format_RGB32; j < QImage::Format_Alpha8; ++j) { + if (i == j) + continue; + QString test = QString::fromLatin1("%1 -> %2").arg(formatToString(QImage::Format(i))).arg(formatToString(QImage::Format(j))); + QTest::newRow(qPrintable(test)) << QImage::Format(i) << QImage::Format(j); + } + } +} + +void tst_QImage::inplaceRgbConversion() { // Test that conversions between RGB formats of the same bitwidth can be done inplace. #if defined(Q_COMPILER_REF_QUALIFIERS) @@ -2580,13 +2664,22 @@ void tst_QImage::inplaceConversion() QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16); } } - if (image.depth() == imageConverted.depth()) + bool expectInplace = image.depth() == imageConverted.depth(); + // RGB30 <-> RGB32 have a few direct conversions without inplace counterparts. + if (format >= QImage::Format_BGR30 && format <= QImage::Format_A2RGB30_Premultiplied + && dest_format >= QImage::Format_RGB32 && dest_format <= QImage::Format_ARGB32_Premultiplied) + expectInplace = false; + if (dest_format >= QImage::Format_BGR30 && dest_format <= QImage::Format_A2RGB30_Premultiplied + && format >= QImage::Format_RGB32 && format <= QImage::Format_ARGB32_Premultiplied) + expectInplace = false; + + if (expectInplace) QCOMPARE(imageConverted.constScanLine(0), originalPtr); { // Test attempted inplace conversion of images created on existing buffer - static const quint32 readOnlyData[] = { 0x00010203U, 0x04050607U, 0x08091011U, 0x12131415U }; - quint32 readWriteData[] = { 0x00010203U, 0x04050607U, 0x08091011U, 0x12131415U }; + static const quint32 readOnlyData[] = { 0xff0102ffU, 0xff0506ffU, 0xff0910ffU, 0xff1314ffU }; + quint32 readWriteData[] = { 0xff0102ffU, 0xff0506ffU, 0xff0910ffU, 0xff1314ffU }; QImage roImage((const uchar *)readOnlyData, 2, 2, format); QImage roInplaceConverted = std::move(roImage).convertToFormat(dest_format); @@ -2708,18 +2801,9 @@ void tst_QImage::invertPixelsRGB_data() { QTest::addColumn("image_format"); - QTest::newRow("invertPixels RGB16") << QImage::Format_RGB16; - QTest::newRow("invertPixels RGB32") << QImage::Format_RGB32; - QTest::newRow("invertPixels BGR30") << QImage::Format_BGR30; - QTest::newRow("invertPixels RGB444") << QImage::Format_RGB444; - QTest::newRow("invertPixels RGB555") << QImage::Format_RGB555; - QTest::newRow("invertPixels RGB888") << QImage::Format_RGB888; - - QTest::newRow("invertPixels ARGB32") << QImage::Format_ARGB32; - QTest::newRow("invertPixels ARGB32pm") << QImage::Format_ARGB32_Premultiplied; - QTest::newRow("invertPixels RGBA8888") << QImage::Format_RGBA8888; - QTest::newRow("invertPixels RGBA8888pm") << QImage::Format_RGBA8888_Premultiplied; - QTest::newRow("invertPixels RGBA4444pm") << QImage::Format_ARGB4444_Premultiplied; + for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) { + QTest::newRow(qPrintable(formatToString(QImage::Format(i)))) << QImage::Format(i); + } } void tst_QImage::invertPixelsRGB() From 041cbe4b38fcd19212fec2af35140d947a3dac91 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 27 Apr 2015 15:03:09 +0200 Subject: [PATCH 16/29] Add missing RGB32 <-> RGB30 convertions Completes the inplace converters so that we can rely on inplace conversions to succede as long as the image depth is the same. Change-Id: Ia1ae34b5de1bc16e87ff5403bdacfcae44a22791 Reviewed-by: Gunnar Sletta --- src/gui/image/qimage_conversions.cpp | 120 +++++++++++++----- tests/auto/gui/image/qimage/tst_qimage.cpp | 11 +- .../qimageconversion/tst_qimageconversion.cpp | 110 ++++++++++++---- 3 files changed, 172 insertions(+), 69 deletions(-) diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 74ad1127a97..e0ca2c53313 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -497,8 +497,7 @@ static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::Im { Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32); - Q_ASSERT(dest->format == QImage::Format_BGR30 || dest->format == QImage::Format_A2BGR30_Premultiplied - || dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_A2RGB30_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_BGR30 || dest->format == QImage::Format_RGB30); Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); @@ -520,28 +519,24 @@ static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::Im } template -static void convert_RGB30_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +static bool convert_RGB_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags) { - Q_ASSERT(src->format == QImage::Format_BGR30 || src->format == QImage::Format_RGB30); - Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); + Q_ASSERT(data->format == QImage::Format_RGB32 || data->format == QImage::Format_ARGB32); - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const quint32 *src_data = (quint32 *) src->data; - quint32 *dest_data = (quint32 *) dest->data; + const int pad = (data->bytes_per_line >> 2) - data->width; + QRgb *rgb_data = (QRgb *) data->data; - for (int i = 0; i < src->height; ++i) { - const quint32 *end = src_data + src->width; - while (src_data < end) { - *dest_data = qConvertA2rgb30ToArgb32(*src_data); - ++src_data; - ++dest_data; + for (int i = 0; i < data->height; ++i) { + const QRgb *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = qConvertRgb32ToRgb30(*rgb_data); + ++rgb_data; } - src_data += src_pad; - dest_data += dest_pad; + rgb_data += pad; } + + data->format = (PixelOrder == PixelOrderRGB) ? QImage::Format_RGB30 : QImage::Format_BGR30; + return true; } static inline uint qUnpremultiplyRgb30(uint rgb30) @@ -695,6 +690,51 @@ static bool convert_BGR30_to_A2RGB30_inplace(QImageData *data, Qt::ImageConversi return true; } +template +static void convert_A2RGB30_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_ARGB32); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const int src_pad = (src->bytes_per_line >> 2) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertA2rgb30ToArgb32(qUnpremultiplyRgb30(*src_data)); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template +static bool convert_A2RGB30_PM_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied); + + const int pad = (data->bytes_per_line >> 2) - data->width; + uint *rgb_data = (uint *) data->data; + + for (int i = 0; i < data->height; ++i) { + const uint *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = qConvertA2rgb30ToArgb32(qUnpremultiplyRgb30(*rgb_data)); + ++rgb_data; + } + rgb_data += pad; + } + data->format = QImage::Format_ARGB32; + return true; +} + static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_Indexed8); @@ -2007,9 +2047,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, convert_RGB_to_RGB30, - convert_RGB_to_RGB30, - convert_RGB_to_RGB30, + 0, convert_RGB_to_RGB30, + 0, 0, 0 }, // Format_RGB32 @@ -2341,9 +2381,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_RGB30_to_RGB, - convert_RGB30_to_RGB, - convert_RGB30_to_RGB, + 0, + 0, + 0, 0, 0, 0, @@ -2368,7 +2408,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, + convert_A2RGB30_PM_to_ARGB, 0, 0, 0, @@ -2393,9 +2433,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_RGB30_to_RGB, - convert_RGB30_to_RGB, - convert_RGB30_to_RGB, + 0, + 0, + 0, 0, 0, 0, @@ -2420,7 +2460,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, + convert_A2RGB30_PM_to_ARGB, 0, 0, 0, @@ -2536,7 +2576,11 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, 0, 0, 0, 0, 0 + convert_RGB_to_RGB30_inplace, + 0, + convert_RGB_to_RGB30_inplace, + 0, + 0, 0 }, // Format_RGB32 { 0, @@ -2562,7 +2606,11 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_ARGB_to_RGBA_inplace, convert_ARGB_to_RGBA_inplace, 0, - 0, 0, 0, 0, 0, 0 + convert_RGB_to_RGB30_inplace, + 0, + convert_RGB_to_RGB30_inplace, + 0, + 0, 0 }, // Format_ARGB32 { 0, @@ -2584,7 +2632,11 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, convert_ARGB_to_RGBA_inplace, - 0, 0, 0, 0, 0, 0 + 0, + 0, + 0, + 0, + 0, 0 }, // Format_ARGB32_Premultiplied { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 @@ -2716,7 +2768,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + convert_A2RGB30_PM_to_ARGB_inplace, 0, 0, 0, @@ -2768,7 +2820,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + convert_A2RGB30_PM_to_ARGB_inplace, 0, 0, 0, diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index fa2aae66584..2931185c8b5 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -2664,16 +2664,7 @@ void tst_QImage::inplaceRgbConversion() QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16); } } - bool expectInplace = image.depth() == imageConverted.depth(); - // RGB30 <-> RGB32 have a few direct conversions without inplace counterparts. - if (format >= QImage::Format_BGR30 && format <= QImage::Format_A2RGB30_Premultiplied - && dest_format >= QImage::Format_RGB32 && dest_format <= QImage::Format_ARGB32_Premultiplied) - expectInplace = false; - if (dest_format >= QImage::Format_BGR30 && dest_format <= QImage::Format_A2RGB30_Premultiplied - && format >= QImage::Format_RGB32 && format <= QImage::Format_ARGB32_Premultiplied) - expectInplace = false; - - if (expectInplace) + if (image.depth() == imageConverted.depth()) QCOMPARE(imageConverted.constScanLine(0), originalPtr); { diff --git a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp index 2d4a453b58e..bca5868c3fb 100644 --- a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp +++ b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp @@ -49,6 +49,12 @@ private slots: void convertRgb32ToRgb888_data(); void convertRgb32ToRgb888(); + void convertRgb16_data(); + void convertRgb16(); + + void convertRgb32_data(); + void convertRgb32(); + void convertGeneric_data(); void convertGeneric(); @@ -146,55 +152,96 @@ void tst_QImageConversion::convertRgb32ToRgb888() } } - -void tst_QImageConversion::convertGeneric_data() +void tst_QImageConversion::convertRgb16_data() { QTest::addColumn("inputImage"); QTest::addColumn("outputFormat"); QImage rgb16 = generateImageRgb16(1000, 1000); + + QTest::newRow("rgb32") << rgb16 << QImage::Format_RGB32; + QTest::newRow("rgb888") << rgb16 << QImage::Format_RGB888; + QTest::newRow("rgb666") << rgb16 << QImage::Format_RGB666; + QTest::newRow("rgb555") << rgb16 << QImage::Format_RGB555; +} + +void tst_QImageConversion::convertRgb16() +{ + QFETCH(QImage, inputImage); + QFETCH(QImage::Format, outputFormat); + + QBENCHMARK { + QImage output = inputImage.convertToFormat(outputFormat); + output.constBits(); + } +} + +void tst_QImageConversion::convertRgb32_data() +{ + QTest::addColumn("inputImage"); + QTest::addColumn("outputFormat"); QImage rgb32 = generateImageRgb32(1000, 1000); QImage argb32 = generateImageArgb32(1000, 1000); QImage argb32pm = argb32.convertToFormat(QImage::Format_ARGB32_Premultiplied); - QImage rgba32 = argb32.convertToFormat(QImage::Format_RGBA8888); - QImage a2rgb30 = argb32.convertToFormat(QImage::Format_A2RGB30_Premultiplied); - - QTest::newRow("rgb16 -> rgb32") << rgb16 << QImage::Format_RGB32; - QTest::newRow("rgb16 -> rgb888") << rgb16 << QImage::Format_RGB888; - QTest::newRow("rgb16 -> rgb666") << rgb16 << QImage::Format_RGB666; - QTest::newRow("rgb16 -> rgb555") << rgb16 << QImage::Format_RGB555; QTest::newRow("rgb32 -> rgb16") << rgb32 << QImage::Format_RGB16; - QTest::newRow("rgb32 -> rgb888") << rgb32 << QImage::Format_RGB888; - QTest::newRow("rgb32 -> rgb666") << rgb32 << QImage::Format_RGB666; - QTest::newRow("rgb32 -> rgb555") << rgb32 << QImage::Format_RGB555; QTest::newRow("rgb32 -> argb32") << rgb32 << QImage::Format_ARGB32; QTest::newRow("rgb32 -> argb32pm") << rgb32 << QImage::Format_ARGB32_Premultiplied; QTest::newRow("rgb32 -> rgbx8888") << rgb32 << QImage::Format_RGBX8888; QTest::newRow("rgb32 -> rgba8888") << rgb32 << QImage::Format_RGBA8888; QTest::newRow("rgb32 -> rgba8888pm") << rgb32 << QImage::Format_RGBA8888_Premultiplied; QTest::newRow("rgb32 -> rgb30") << rgb32 << QImage::Format_RGB30; - QTest::newRow("rgb32 -> bgr30") << rgb32 << QImage::Format_BGR30; + QTest::newRow("rgb32 -> a2bgr30") << rgb32 << QImage::Format_A2BGR30_Premultiplied; + QTest::newRow("rgb32 -> rgb888") << rgb32 << QImage::Format_RGB888; + QTest::newRow("rgb32 -> rgb666") << rgb32 << QImage::Format_RGB666; + QTest::newRow("rgb32 -> rgb555") << rgb32 << QImage::Format_RGB555; - QTest::newRow("argb32 -> rgb888") << argb32 << QImage::Format_RGB888; - QTest::newRow("argb32 -> rgb666") << argb32 << QImage::Format_RGB666; - QTest::newRow("argb32 -> argb8565pm") << argb32 << QImage::Format_ARGB8565_Premultiplied; - QTest::newRow("argb32 -> argb4444pm") << argb32 << QImage::Format_ARGB4444_Premultiplied; + QTest::newRow("argb32 -> rgb16") << argb32 << QImage::Format_RGB16; QTest::newRow("argb32 -> rgb32") << argb32 << QImage::Format_RGB32; QTest::newRow("argb32 -> argb32pm") << argb32 << QImage::Format_ARGB32_Premultiplied; QTest::newRow("argb32 -> rgbx8888") << argb32 << QImage::Format_RGBX8888; QTest::newRow("argb32 -> rgba8888") << argb32 << QImage::Format_RGBA8888; QTest::newRow("argb32 -> rgba8888pm") << argb32 << QImage::Format_RGBA8888_Premultiplied; QTest::newRow("argb32 -> rgb30") << argb32 << QImage::Format_RGB30; - QTest::newRow("argb32 -> a2rgb30") << argb32 << QImage::Format_A2RGB30_Premultiplied; + QTest::newRow("argb32 -> a2bgr30") << argb32 << QImage::Format_A2BGR30_Premultiplied; + QTest::newRow("argb32 -> rgb888") << argb32 << QImage::Format_RGB888; + QTest::newRow("argb32 -> rgb666") << argb32 << QImage::Format_RGB666; + QTest::newRow("argb32 -> argb8565pm") << argb32 << QImage::Format_ARGB8565_Premultiplied; + QTest::newRow("argb32 -> argb4444pm") << argb32 << QImage::Format_ARGB4444_Premultiplied; - QTest::newRow("argb32pm -> argb4444pm") << argb32pm << QImage::Format_ARGB4444_Premultiplied; + QTest::newRow("argb32pm -> rgb16") << argb32pm << QImage::Format_RGB16; QTest::newRow("argb32pm -> rgb32") << argb32pm << QImage::Format_RGB32; QTest::newRow("argb32pm -> argb32") << argb32pm << QImage::Format_ARGB32; QTest::newRow("argb32pm -> rgbx8888") << argb32pm << QImage::Format_RGBX8888; QTest::newRow("argb32pm -> rgba8888") << argb32pm << QImage::Format_RGBA8888; QTest::newRow("argb32pm -> rgba8888pm") << argb32pm << QImage::Format_RGBA8888_Premultiplied; QTest::newRow("argb32pm -> rgb30") << argb32pm << QImage::Format_RGB30; - QTest::newRow("argb32pm -> a2rgb30") << argb32pm << QImage::Format_A2RGB30_Premultiplied; + QTest::newRow("argb32pm -> a2bgr30") << argb32pm << QImage::Format_A2BGR30_Premultiplied; + QTest::newRow("argb32pm -> rgb888") << argb32pm << QImage::Format_RGB888; + QTest::newRow("argb32pm -> rgb666") << argb32pm << QImage::Format_RGB666; + QTest::newRow("argb32pm -> argb8565pm") << argb32pm << QImage::Format_ARGB8565_Premultiplied; + QTest::newRow("argb32pm -> argb4444pm") << argb32pm << QImage::Format_ARGB4444_Premultiplied; +} + +void tst_QImageConversion::convertRgb32() +{ + QFETCH(QImage, inputImage); + QFETCH(QImage::Format, outputFormat); + + QBENCHMARK { + QImage output = inputImage.convertToFormat(outputFormat); + output.constBits(); + } +} + +void tst_QImageConversion::convertGeneric_data() +{ + QTest::addColumn("inputImage"); + QTest::addColumn("outputFormat"); + QImage rgb32 = generateImageRgb32(1000, 1000); + QImage argb32 = generateImageArgb32(1000, 1000); + QImage rgba32 = argb32.convertToFormat(QImage::Format_RGBA8888); + QImage bgr30 = rgb32.convertToFormat(QImage::Format_BGR30); + QImage a2rgb30 = argb32.convertToFormat(QImage::Format_A2RGB30_Premultiplied); QTest::newRow("rgba8888 -> rgb32") << rgba32 << QImage::Format_RGB32; QTest::newRow("rgba8888 -> argb32") << rgba32 << QImage::Format_ARGB32; @@ -202,7 +249,16 @@ void tst_QImageConversion::convertGeneric_data() QTest::newRow("rgba8888 -> rgbx8888") << rgba32 << QImage::Format_RGBX8888; QTest::newRow("rgba8888 -> rgba8888pm") << rgba32 << QImage::Format_RGBA8888_Premultiplied; QTest::newRow("rgba8888 -> rgb30") << rgba32 << QImage::Format_RGB30; - QTest::newRow("rgba8888 -> a2rgb30") << rgba32 << QImage::Format_A2RGB30_Premultiplied; + QTest::newRow("rgba8888 -> a2bgr30") << rgba32 << QImage::Format_A2BGR30_Premultiplied; + + QTest::newRow("bgr30 -> rgb32") << bgr30 << QImage::Format_RGB32; + QTest::newRow("bgr30 -> argb32") << bgr30 << QImage::Format_ARGB32; + QTest::newRow("bgr30 -> argb32pm") << bgr30 << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("bgr30 -> rgbx8888") << bgr30 << QImage::Format_RGBX8888; + QTest::newRow("bgr30 -> rgba8888") << bgr30 << QImage::Format_RGBA8888; + QTest::newRow("bgr30 -> rgba8888pm") << bgr30 << QImage::Format_RGBA8888_Premultiplied; + QTest::newRow("bgr30 -> rgb30") << bgr30 << QImage::Format_RGB30; + QTest::newRow("bgr30 -> a2bgr30") << bgr30 << QImage::Format_A2BGR30_Premultiplied; QTest::newRow("a2rgb30 -> rgb32") << a2rgb30 << QImage::Format_RGB32; QTest::newRow("a2rgb30 -> argb32") << a2rgb30 << QImage::Format_ARGB32; @@ -210,7 +266,9 @@ void tst_QImageConversion::convertGeneric_data() QTest::newRow("a2rgb30 -> rgbx8888") << a2rgb30 << QImage::Format_RGBX8888; QTest::newRow("a2rgb30 -> rgba8888") << a2rgb30 << QImage::Format_RGBA8888; QTest::newRow("a2rgb30 -> rgba8888pm") << a2rgb30 << QImage::Format_RGBA8888_Premultiplied; + QTest::newRow("a2rgb30 -> rgb30") << a2rgb30 << QImage::Format_RGB30; QTest::newRow("a2rgb30 -> bgr30") << a2rgb30 << QImage::Format_BGR30; + QTest::newRow("a2rgb30 -> a2bgr30") << a2rgb30 << QImage::Format_A2BGR30_Premultiplied; } void tst_QImageConversion::convertGeneric() @@ -316,12 +374,14 @@ QImage tst_QImageConversion::generateImageRgb32(int width, int height) QImage tst_QImageConversion::generateImageArgb32(int width, int height) { QImage image(width, height, QImage::Format_ARGB32); - const int byteWidth = width * 4; for (int y = 0; y < image.height(); ++y) { - uchar *scanline = image.scanLine(y); - for (int x = 0; x < byteWidth; ++x) - scanline[x] = x ^ y; + QRgb *scanline = (QRgb*)image.scanLine(y); + for (int x = 0; x < width; ++x) { + int alpha = (x ^ y) & 0x1ff; + alpha = qMax(0, qMin(alpha - 128, 255)); + scanline[x] = qRgba(x, y, x ^ y, alpha); + } } return image; } From 6c4b0e443ff92a4d8cb640ab549fe114fd9d5a29 Mon Sep 17 00:00:00 2001 From: Romain Pokrzywka Date: Wed, 29 Apr 2015 10:05:48 -0700 Subject: [PATCH 17/29] Move QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO definition to gcc-base.conf The flags are the same across all GCC flavors so put the definition in the common gcc-base.conf instead of duplicating it in g++-base.conf and clang.conf Change-Id: I1ba2c3c314d3a02b559c384aecef74240f69f659 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Oswald Buddenhagen --- mkspecs/common/clang.conf | 2 -- mkspecs/common/g++-base.conf | 4 ---- mkspecs/common/gcc-base.conf | 3 +++ 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf index 76a4b661297..a0a2b3f3d1f 100644 --- a/mkspecs/common/clang.conf +++ b/mkspecs/common/clang.conf @@ -16,14 +16,12 @@ QMAKE_LINK_SHLIB = $$QMAKE_CXX CONFIG += clang_pch_style QMAKE_PCH_OUTPUT_EXT = .pch -QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -g QMAKE_CFLAGS_ISYSTEM = -isystem QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} QMAKE_CFLAGS_USE_PRECOMPILE = -Xclang -include-pch -Xclang ${QMAKE_PCH_OUTPUT} QMAKE_CFLAGS_LTCG = -flto QMAKE_CFLAGS_DISABLE_LTCG = -fno-lto -QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG diff --git a/mkspecs/common/g++-base.conf b/mkspecs/common/g++-base.conf index 99c0d8078f8..d687dbc3f32 100644 --- a/mkspecs/common/g++-base.conf +++ b/mkspecs/common/g++-base.conf @@ -15,15 +15,11 @@ QMAKE_CC = gcc QMAKE_LINK_C = $$QMAKE_CC QMAKE_LINK_C_SHLIB = $$QMAKE_CC -QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -g - QMAKE_CXX = g++ QMAKE_LINK = $$QMAKE_CXX QMAKE_LINK_SHLIB = $$QMAKE_CXX -QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO - QMAKE_PCH_OUTPUT_EXT = .gch QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf index ff89accace6..dc0aa4b4a96 100644 --- a/mkspecs/common/gcc-base.conf +++ b/mkspecs/common/gcc-base.conf @@ -39,6 +39,7 @@ QMAKE_CFLAGS_DEPS += -M QMAKE_CFLAGS_WARN_ON += -Wall -W QMAKE_CFLAGS_WARN_OFF += -w QMAKE_CFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE +QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -g QMAKE_CFLAGS_DEBUG += -g QMAKE_CFLAGS_SHLIB += -fPIC QMAKE_CFLAGS_STATIC_LIB += -fPIC @@ -57,6 +58,7 @@ QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB @@ -73,6 +75,7 @@ QMAKE_LFLAGS += QMAKE_LFLAGS_DEBUG += QMAKE_LFLAGS_APP += QMAKE_LFLAGS_RELEASE += +QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO += QMAKE_LFLAGS_EXCEPTIONS_OFF += QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG -fuse-linker-plugin From a37daf99ad275d6e3e218504ec573f10fb18a48c Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 16 Apr 2015 16:53:20 +0400 Subject: [PATCH 18/29] [DiagLib] Sync QChar enums These values were added as part of upgrading to Unicode 7.0 Change-Id: Ib208828a7685ba4f89f0e2f06033f74c8ff13532 Reviewed-by: Andy Shaw --- tests/manual/diaglib/textdump.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/manual/diaglib/textdump.cpp b/tests/manual/diaglib/textdump.cpp index 40295f88336..ed4d5021be5 100644 --- a/tests/manual/diaglib/textdump.cpp +++ b/tests/manual/diaglib/textdump.cpp @@ -222,6 +222,32 @@ static const EnumLookup scriptEnumLookup[] = {QChar::Script_Sharada, "Script_Sharada"}, {QChar::Script_SoraSompeng, "Script_SoraSompeng"}, {QChar::Script_Takri, "Script_Takri"}, + +#if QT_VERSION >= 0x050500 + {QChar::Script_CaucasianAlbanian, "Script_CaucasianAlbanian"}, + {QChar::Script_BassaVah, "Script_BassaVah"}, + {QChar::Script_Duployan, "Script_Duployan"}, + {QChar::Script_Elbasan, "Script_Elbasan"}, + {QChar::Script_Grantha, "Script_Grantha"}, + {QChar::Script_PahawhHmong, "Script_PahawhHmong"}, + {QChar::Script_Khojki, "Script_Khojki"}, + {QChar::Script_LinearA, "Script_LinearA"}, + {QChar::Script_Mahajani, "Script_Mahajani"}, + {QChar::Script_Manichaean, "Script_Manichaean"}, + {QChar::Script_MendeKikakui, "Script_MendeKikakui"}, + {QChar::Script_Modi, "Script_Modi"}, + {QChar::Script_Mro, "Script_Mro"}, + {QChar::Script_OldNorthArabian, "Script_OldNorthArabian"}, + {QChar::Script_Nabataean, "Script_Nabataean"}, + {QChar::Script_Palmyrene, "Script_Palmyrene"}, + {QChar::Script_PauCinHau, "Script_PauCinHau"}, + {QChar::Script_OldPermic, "Script_OldPermic"}, + {QChar::Script_PsalterPahlavi, "Script_PsalterPahlavi"}, + {QChar::Script_Siddham, "Script_Siddham"}, + {QChar::Script_Khudawadi, "Script_Khudawadi"}, + {QChar::Script_Tirhuta, "Script_Tirhuta"}, + {QChar::Script_WarangCiti, "Script_WarangCiti"}, +#endif // Qt 5.5 }; #endif // Qt 5.1 @@ -335,6 +361,9 @@ static const EnumLookup unicodeVersionEnumLookup[] = {QChar::Unicode_6_1, "Unicode_6_1"}, {QChar::Unicode_6_2, "Unicode_6_2"}, {QChar::Unicode_6_3, "Unicode_6_3"}, +#if QT_VERSION >= 0x050500 + {QChar::Unicode_7_0, "Unicode_7_0"}, +#endif // Qt 5.5 #endif // Qt 5 }; From 7443b3c9493ebed90397eaa4f3622e76e3131d10 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 22 Apr 2015 05:28:08 +0400 Subject: [PATCH 19/29] Optimize QFont::resolve(const QFont &other) When resolve_mask is 0, the font inherits just everything, and there is no need in checking for any resolved attributes; the resolved font always inherits dpi, so do not check it either. Change-Id: Ie5d7ced0859d46a9237447e29051a22569480a51 Reviewed-by: Simon Hausmann --- src/gui/text/qfont.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index a5fade99fda..ce39645246f 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1724,10 +1724,8 @@ bool QFont::rawMode() const */ QFont QFont::resolve(const QFont &other) const { - if (*this == other - && (resolve_mask == other.resolve_mask || resolve_mask == 0) - && d->dpi == other.d->dpi) { - QFont o = other; + if (resolve_mask == 0 || (resolve_mask == other.resolve_mask && *this == other)) { + QFont o(other); o.resolve_mask = resolve_mask; return o; } From af217e67fa024e4ad9d492ef7af4fe8005993d3f Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 22 Apr 2015 05:30:56 +0400 Subject: [PATCH 20/29] Minor optimization to QWidgetPrivate::setFont_helper() There is no sense in comparing fonts with different resolve_mask-s. Change-Id: Icfdaf494fce8a59b7138d96fdf7354cc0514ca6a Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidget_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 94254262158..fe65cb19c7d 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -358,7 +358,7 @@ public: void updateFont(const QFont &); inline void setFont_helper(const QFont &font) { - if (data.fnt == font && data.fnt.resolve() == font.resolve()) + if (data.fnt.resolve() == font.resolve() && data.fnt == font) return; updateFont(font); } From 9bf6ea7fde7228c8fcc669162969120a356b4d15 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 24 Apr 2015 05:29:07 +0400 Subject: [PATCH 21/29] [QFontDatabase] Get rid of some dead code 1. Checking if `db->count == 0` inside the `for (int x = 0; x < db->count; ++x)` loop makes absolutely no sense; 2. The family gets loaded just a line above (ensurePopulated()). Change-Id: I72dbd42565c4f5a5d9ff8879f10ee0ece7298fa7 Reviewed-by: Simon Hausmann --- src/gui/text/qfontdatabase.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 0f3cb21c70d..af3fe729488 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1181,9 +1181,6 @@ static int match(int script, const QFontDef &request, test.family->ensurePopulated(); - if (family_name.isEmpty()) - load(test.family->name, script); - // Check if family is supported in the script we want if (writingSystem != QFontDatabase::Any && !(test.family->writingSystems[writingSystem] & QtFontFamily::Supported)) continue; From a77dc1a669ed197514fe29333b94e037f5285cd8 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 24 Apr 2015 05:48:22 +0400 Subject: [PATCH 22/29] [QFontDatabase] Drop QtFontDesc's familyIndex member Many times set but never used. Change-Id: I297f21d4b9878e5f9559a2dfdb2d3de34107bb7d Reviewed-by: Simon Hausmann Reviewed-by: Friedemann Kleint --- src/gui/text/qfontdatabase.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index af3fe729488..f3e071a20a0 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -617,13 +617,12 @@ static void parseFontName(const QString &name, QString &foundry, QString &family struct QtFontDesc { - inline QtFontDesc() : family(0), foundry(0), style(0), size(0), encoding(0), familyIndex(-1) {} + inline QtFontDesc() : family(0), foundry(0), style(0), size(0), encoding(0) {} QtFontFamily *family; QtFontFoundry *foundry; QtFontStyle *style; QtFontSize *size; QtFontEncoding *encoding; - int familyIndex; }; static int match(int script, const QFontDef &request, @@ -1157,7 +1156,6 @@ static int match(int script, const QFontDef &request, desc->style = 0; desc->size = 0; desc->encoding = 0; - desc->familyIndex = -1; unsigned int score = ~0u; @@ -1174,7 +1172,6 @@ static int match(int script, const QFontDef &request, continue; QtFontDesc test; test.family = db->families[x]; - test.familyIndex = x; if (!matchFamilyName(family_name, test.family)) continue; From 3ce2dd391e30bde9387ddf9e84b159dcd0ad3c07 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 24 Apr 2015 06:10:49 +0400 Subject: [PATCH 23/29] [QFontDatabase] Get rid of QtFontEncoding This one has not been unsed for ages (since Qt3?). Change-Id: Iaf514db1b698b34a303f34c150b72db989eb176c Reviewed-by: Simon Hausmann Reviewed-by: Friedemann Kleint --- src/gui/text/qfontdatabase.cpp | 38 +++++++--------------------------- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index f3e071a20a0..126f0bf3ecd 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -172,16 +172,6 @@ static int getFontWeight(const QString &weightString) return QFont::Normal; } -struct QtFontEncoding -{ - signed int encoding : 16; - - uint xpoint : 16; - uint xres : 8; - uint yres : 8; - uint avgwidth : 16; - uchar pitch : 8; -}; struct QtFontSize { @@ -617,18 +607,13 @@ static void parseFontName(const QString &name, QString &foundry, QString &family struct QtFontDesc { - inline QtFontDesc() : family(0), foundry(0), style(0), size(0), encoding(0) {} + inline QtFontDesc() : family(0), foundry(0), style(0), size(0) {} QtFontFamily *family; QtFontFoundry *foundry; QtFontStyle *style; QtFontSize *size; - QtFontEncoding *encoding; }; -static int match(int script, const QFontDef &request, - const QString &family_name, const QString &foundry_name, int force_encoding_id, - QtFontDesc *desc, const QList &blacklisted); - static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi) { fontDef->family = desc.family->name; @@ -980,16 +965,14 @@ static unsigned int bestFoundry(int script, unsigned int score, int styleStrategy, const QtFontFamily *family, const QString &foundry_name, QtFontStyle::Key styleKey, int pixelSize, char pitch, - QtFontDesc *desc, int force_encoding_id, const QString &styleName = QString()) + QtFontDesc *desc, const QString &styleName = QString()) { - Q_UNUSED(force_encoding_id); Q_UNUSED(script); Q_UNUSED(pitch); desc->foundry = 0; desc->style = 0; desc->size = 0; - desc->encoding = 0; FM_DEBUG(" REMARK: looking for best foundry for family '%s' [%d]", family->name.toLatin1().constData(), family->count); @@ -1083,8 +1066,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy, enum { PitchMismatch = 0x4000, StyleMismatch = 0x2000, - BitmapScaledPenalty = 0x1000, - EncodingMismatch = 0x0002 + BitmapScaledPenalty = 0x1000 }; if (pitch != '*') { if ((pitch == 'm' && !family->fixedPitch) @@ -1127,10 +1109,9 @@ static bool matchFamilyName(const QString &familyName, QtFontFamily *f) Tries to find the best match for a given request and family/foundry */ static int match(int script, const QFontDef &request, - const QString &family_name, const QString &foundry_name, int force_encoding_id, + const QString &family_name, const QString &foundry_name, QtFontDesc *desc, const QList &blacklistedFamilies) { - Q_UNUSED(force_encoding_id); int result = -1; QtFontStyle::Key styleKey; @@ -1155,7 +1136,6 @@ static int match(int script, const QFontDef &request, desc->foundry = 0; desc->style = 0; desc->size = 0; - desc->encoding = 0; unsigned int score = ~0u; @@ -1187,13 +1167,13 @@ static int match(int script, const QFontDef &request, unsigned int newscore = bestFoundry(script, score, request.styleStrategy, test.family, foundry_name, styleKey, request.pixelSize, pitch, - &test, force_encoding_id, request.styleName); + &test, request.styleName); if (test.foundry == 0 && !foundry_name.isEmpty()) { // the specific foundry was not found, so look for // any foundry matching our requirements newscore = bestFoundry(script, score, request.styleStrategy, test.family, QString(), styleKey, request.pixelSize, - pitch, &test, force_encoding_id, request.styleName); + pitch, &test, request.styleName); } if (newscore < score) { @@ -2531,8 +2511,6 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, { QMutexLocker locker(fontDatabaseMutex()); - const int force_encoding_id = -1; - if (!privateDb()->count) initializeDb(); @@ -2555,7 +2533,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, QtFontDesc desc; QList blackListed; - int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed); + int index = match(script, request, family_name, foundry_name, &desc, blackListed); if (index >= 0) { engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size); if (!engine) @@ -2598,7 +2576,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, if (!engine) { QtFontDesc desc; do { - index = match(script, def, def.family, QLatin1String(""), 0, &desc, blackListed); + index = match(script, def, def.family, QLatin1String(""), &desc, blackListed); if (index >= 0) { QFontDef loadDef = def; if (loadDef.family.isEmpty()) From 315b359bc199fcc9492fa33f573d6c43d22b3b6a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 28 Apr 2015 08:44:53 +0200 Subject: [PATCH 24/29] QFileDialog: Stabilize tests. The init()/cleanup() code in tst_qfiledialog and tst_qfiledialog2 currently differs and fails to clean up the settings file since it only removes the legacy settings under the Qt group and instantiates a new QFileDialog while the QSettings class is still in scope. Also, it has no means of clearing the setLastVisitedDirectory(), which causes the tst_QFiledialog::completer() and tst_QFiledialog::history() tests to interfere, leaving the settings in an invalid state. tst_qfiledialog2 does not use QStandardPaths::setTestModeEnabled((). - Ensure the last visited URL is always clean by making QFileDialogPrivate::setLastVisitedDirectory() static and calling it from init(). - Introduce a cleanupSettingsFile() function to the tests that cleans both groups and call it from initTestCase() and cleanup() to ensure a clean state. - Add QStandardPaths::setTestModeEnabled() to tst_qfiledialog2. Fixes sporadic test fails when executing tst_QFiledialog::completer() and tst_QFiledialog::history() in a sequence. Task-number: QTBUG-45764 Change-Id: I24de3caabf77be067b385d64ff11b7a07fe12b72 Reviewed-by: Simon Hausmann --- src/widgets/dialogs/qfiledialog.cpp | 4 +- src/widgets/dialogs/qfiledialog_p.h | 2 +- .../dialogs/qfiledialog/tst_qfiledialog.cpp | 29 ++++++++++---- .../dialogs/qfiledialog2/tst_qfiledialog2.cpp | 39 ++++++++++++------- 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 9e5548ab4cc..8590467abcb 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -906,7 +906,7 @@ void QFileDialog::setDirectory(const QString &directory) return; QUrl newDirUrl = QUrl::fromLocalFile(newDirectory); - d->setLastVisitedDirectory(newDirUrl); + QFileDialogPrivate::setLastVisitedDirectory(newDirUrl); d->options->setInitialDirectory(QUrl::fromLocalFile(directory)); if (!d->usingWidgets()) { @@ -967,7 +967,7 @@ void QFileDialog::setDirectoryUrl(const QUrl &directory) if (!directory.isValid()) return; - d->setLastVisitedDirectory(directory); + QFileDialogPrivate::setLastVisitedDirectory(directory); d->options->setInitialDirectory(directory); if (d->nativeDialogInUse) diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index 8a108969665..f610e46f83f 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -187,7 +187,7 @@ public: #endif bool restoreWidgetState(QStringList &history, int splitterPosition); - void setLastVisitedDirectory(const QUrl &dir); + static void setLastVisitedDirectory(const QUrl &dir); void retranslateWindowTitle(); void retranslateStrings(); void emitFilesSelected(const QStringList &files); diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index e677891ce5e..ffc000a4182 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -54,10 +54,10 @@ #include #include #include +#include #if defined QT_BUILD_INTERNAL #include #include -#include #endif #include #include @@ -108,6 +108,7 @@ public: public slots: void initTestCase(); void init(); + void cleanup(); private slots: void currentChangedSignal(); @@ -166,7 +167,7 @@ private slots: void rejectModalDialogs(); private: - QByteArray userSettings; + void cleanupSettingsFile(); }; tst_QFiledialog::tst_QFiledialog() @@ -177,18 +178,27 @@ tst_QFiledialog::~tst_QFiledialog() { } +void tst_QFiledialog::cleanupSettingsFile() +{ + // clean up the sidebar between each test + QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); + settings.beginGroup(QLatin1String("FileDialog")); + settings.remove(QString()); + settings.endGroup(); + settings.beginGroup(QLatin1String("Qt")); // Compatibility settings + settings.remove(QLatin1String("filedialog")); + settings.endGroup(); +} + void tst_QFiledialog::initTestCase() { QStandardPaths::setTestModeEnabled(true); + cleanupSettingsFile(); } void tst_QFiledialog::init() { - // clean up the sidebar between each test - QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); - settings.beginGroup(QLatin1String("Qt")); - settings.remove(QLatin1String("filedialog")); - + QFileDialogPrivate::setLastVisitedDirectory(QUrl()); // populate the sidebar with some default settings QNonNativeFileDialog fd; #if defined(Q_OS_WINCE) @@ -196,6 +206,11 @@ void tst_QFiledialog::init() #endif } +void tst_QFiledialog::cleanup() +{ + cleanupSettingsFile(); +} + class MyAbstractItemDelegate : public QAbstractItemDelegate { public: diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp index 7af62cb2a19..ed34c67aad3 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp @@ -88,6 +88,7 @@ public: virtual ~tst_QFileDialog2(); public slots: + void initTestCase(); void init(); void cleanup(); @@ -135,13 +136,13 @@ private slots: void dontShowCompleterOnRoot(); private: - QByteArray userSettings; + void cleanupSettingsFile(); + QTemporaryDir tempDir; }; tst_QFileDialog2::tst_QFileDialog2() - : userSettings() - , tempDir(QDir::tempPath() + "/tst_qfiledialog2.XXXXXX") + : tempDir(QDir::tempPath() + "/tst_qfiledialog2.XXXXXX") { #if defined(Q_OS_WINCE) qApp->setAutoMaximizeThreshold(-1); @@ -152,17 +153,29 @@ tst_QFileDialog2::~tst_QFileDialog2() { } -void tst_QFileDialog2::init() +void tst_QFileDialog2::cleanupSettingsFile() +{ + // clean up the sidebar between each test + QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); + settings.beginGroup(QLatin1String("FileDialog")); + settings.remove(QString()); + settings.endGroup(); + settings.beginGroup(QLatin1String("Qt")); // Compatibility settings + settings.remove(QLatin1String("filedialog")); + settings.endGroup(); +} + +void tst_QFileDialog2::initTestCase() { QVERIFY(tempDir.isValid()); + QStandardPaths::setTestModeEnabled(true); + cleanupSettingsFile(); +} - // Save the developers settings so they don't get mad when their sidebar folders are gone. - QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); - settings.beginGroup(QLatin1String("Qt")); - userSettings = settings.value(QLatin1String("filedialog")).toByteArray(); - settings.remove(QLatin1String("filedialog")); - - // populate it with some default settings +void tst_QFileDialog2::init() +{ + QFileDialogPrivate::setLastVisitedDirectory(QUrl()); + // populate the sidebar with some default settings QNonNativeFileDialog fd; #if defined(Q_OS_WINCE) QTest::qWait(1000); @@ -171,9 +184,7 @@ void tst_QFileDialog2::init() void tst_QFileDialog2::cleanup() { - QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); - settings.beginGroup(QLatin1String("Qt")); - settings.setValue(QLatin1String("filedialog"), userSettings); + cleanupSettingsFile(); } #ifdef QT_BUILD_INTERNAL From 985e7d8094437b64378370cedad76c7fb7e24c31 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 1 May 2015 07:56:18 +0400 Subject: [PATCH 25/29] [QTextStream::read.*] Return earlier when nothing has been read There is no any sense in detecting the encoding of an empty string ;) Change-Id: I1c7af07bd7c3e7e7cf67421a2cb3a1123ca57650 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/io/qtextstream.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 6149a04a74c..5fe4cfef9d1 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -447,6 +447,9 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes) bytesRead = device->read(buf, sizeof(buf)); } + if (bytesRead <= 0) + return false; + #ifndef QT_NO_TEXTCODEC // codec auto detection, explicitly defaults to locale encoding if the // codec has been set to 0. @@ -470,9 +473,6 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes) qt_prettyDebug(buf, qMin(32,int(bytesRead)) , int(bytesRead)).constData(), int(sizeof(buf)), int(bytesRead)); #endif - if (bytesRead <= 0) - return false; - int oldReadBufferSize = readBuffer.size(); #ifndef QT_NO_TEXTCODEC // convert to unicode From 70b085c4650da0994d07baa33701ccfd4a452bb8 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 30 Apr 2015 12:44:34 +0200 Subject: [PATCH 26/29] QSortFilterProxyModel: improve formal argument naming for lessThan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make it clear (just like the other methods) that the indexes refer to the source model, not the proxy model. There was already a note in the documentation, but it was at the end of it; instead, change the formal arguments names. Change-Id: Ia9592f2b080ff276a62de1713a9623e0f3a50cf6 Reviewed-by: Tobias Koenig Reviewed-by: Sérgio Martins Reviewed-by: David Faure --- src/corelib/itemmodels/qsortfilterproxymodel.cpp | 10 +++++----- src/corelib/itemmodels/qsortfilterproxymodel.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 3a604c15f4f..922d0f1622e 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -2577,8 +2577,8 @@ void QSortFilterProxyModel::invalidateFilter() /*! Returns \c true if the value of the item referred to by the given - index \a left is less than the value of the item referred to by - the given index \a right, otherwise returns \c false. + index \a source_left is less than the value of the item referred to by + the given index \a source_right, otherwise returns \c false. This function is used as the < operator when sorting, and handles the following QVariant types: @@ -2612,11 +2612,11 @@ void QSortFilterProxyModel::invalidateFilter() \sa sortRole, sortCaseSensitivity, dynamicSortFilter */ -bool QSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +bool QSortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const { 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()); + QVariant l = (source_left.model() ? source_left.model()->data(source_left, d->sort_role) : QVariant()); + QVariant r = (source_right.model() ? source_right.model()->data(source_right, d->sort_role) : QVariant()); switch (l.userType()) { case QVariant::Invalid: return (r.type() != QVariant::Invalid); diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h index 9ba4e48d09d..a08d7c6416b 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.h +++ b/src/corelib/itemmodels/qsortfilterproxymodel.h @@ -111,7 +111,7 @@ public Q_SLOTS: protected: virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; virtual bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const; - virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const; + virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const; void filterChanged(); void invalidateFilter(); From 36919ef1bd4b7e1efd0e9d66ab574700427386b1 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 28 Apr 2015 16:01:48 +0200 Subject: [PATCH 27/29] QRegularExpression: add error strings from PCRE 8.37 Change-Id: Id62abd91c1584e4e63b95afec0520995125fe807 Reviewed-by: Konstantin Ritt Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/tools/qregularexpression.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp index cbc5a0486e8..9950b907208 100644 --- a/src/corelib/tools/qregularexpression.cpp +++ b/src/corelib/tools/qregularexpression.cpp @@ -2657,7 +2657,8 @@ static const char *pcreCompileErrorCodes[] = QT_TRANSLATE_NOOP("QRegularExpression", "parentheses are too deeply nested"), QT_TRANSLATE_NOOP("QRegularExpression", "invalid range in character class"), QT_TRANSLATE_NOOP("QRegularExpression", "group name must start with a non-digit"), - QT_TRANSLATE_NOOP("QRegularExpression", "parentheses are too deeply nested (stack check)") + QT_TRANSLATE_NOOP("QRegularExpression", "parentheses are too deeply nested (stack check)"), + QT_TRANSLATE_NOOP("QRegularExpression", "digits missing in \\x{} or \\o{}") }; #endif // #if 0 From 9ae7e33f28f972ec566d62ab110e173ebe933520 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 23 Apr 2015 17:55:39 +0200 Subject: [PATCH 28/29] Use stdint.h in qopengl headers on MSVC too Task-number: QTBUG-45774 Change-Id: I1505b4ebeb99371ec2099657c9ce05418dd54224 Reviewed-by: Friedemann Kleint Reviewed-by: Sean Harmer --- src/gui/opengl/qopengl.h | 2 +- src/gui/opengl/qopenglext.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index a70bd799976..72abce760d1 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -221,7 +221,7 @@ typedef unsigned long long int uint64_t; typedef long int int32_t; typedef long long int int64_t; typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) +#elif defined(_WIN32) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1600)) #include #elif defined(_WIN32) typedef __int32 int32_t; diff --git a/src/gui/opengl/qopenglext.h b/src/gui/opengl/qopenglext.h index 36bad4ce282..72316ca4962 100644 --- a/src/gui/opengl/qopenglext.h +++ b/src/gui/opengl/qopenglext.h @@ -1399,7 +1399,7 @@ typedef unsigned long long int uint64_t; typedef long int int32_t; typedef long long int int64_t; typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) +#elif defined(_WIN32) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1600)) #include #elif defined(_WIN32) typedef __int32 int32_t; From eb82959d6688f9e58be4b67670afba3649f1f799 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 2 May 2015 10:44:37 -0700 Subject: [PATCH 29/29] Fix undefined behavior in left-shifting into negative It's undefined behavior to left or right-shift a signed integer such that the sign changes. Since SymbolCsbBit is 31, make sure we use unsigned numbers. Found by ICC qplatformfontdatabase.cpp(614): error #68: integer conversion resulted in a change of sign Change-Id: Idf715b895bac4d56b4afffff13da78d294b1248e Reviewed-by: Konstantin Ritt --- src/gui/text/qplatformfontdatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp index 5fa43948aad..502348a79aa 100644 --- a/src/gui/text/qplatformfontdatabase.cpp +++ b/src/gui/text/qplatformfontdatabase.cpp @@ -611,7 +611,7 @@ QSupportedWritingSystems QPlatformFontDatabase::writingSystemsFromTrueTypeBits(q hasScript = true; //qDebug("font %s supports Korean", familyName.latin1()); } - if (codePageRange[0] & (1 << SymbolCsbBit)) { + if (codePageRange[0] & (1U << SymbolCsbBit)) { writingSystems = QSupportedWritingSystems(); hasScript = false; }