diff options
Diffstat (limited to 'tests/auto/gui')
28 files changed, 935 insertions, 199 deletions
diff --git a/tests/auto/gui/image/image.pro b/tests/auto/gui/image/image.pro index 5a74df4c78..f4e2ab20ba 100644 --- a/tests/auto/gui/image/image.pro +++ b/tests/auto/gui/image/image.pro @@ -10,6 +10,7 @@ SUBDIRS=\ qmovie \ qpicture \ qicon \ + qiconhighdpi !qtHaveModule(network): SUBDIRS -= \ qimagereader diff --git a/tests/auto/gui/image/qiconhighdpi/icons/testtheme/16x16/actions/appointment-new.png b/tests/auto/gui/image/qiconhighdpi/icons/testtheme/16x16/actions/appointment-new.png Binary files differnew file mode 100644 index 0000000000..18b7c6781e --- /dev/null +++ b/tests/auto/gui/image/qiconhighdpi/icons/testtheme/16x16/actions/appointment-new.png diff --git a/tests/auto/gui/image/qiconhighdpi/icons/testtheme/22x22/actions/appointment-new.png b/tests/auto/gui/image/qiconhighdpi/icons/testtheme/22x22/actions/appointment-new.png Binary files differnew file mode 100644 index 0000000000..d676ffd463 --- /dev/null +++ b/tests/auto/gui/image/qiconhighdpi/icons/testtheme/22x22/actions/appointment-new.png diff --git a/tests/auto/gui/image/qiconhighdpi/icons/testtheme/22x22@2/actions/appointment-new.png b/tests/auto/gui/image/qiconhighdpi/icons/testtheme/22x22@2/actions/appointment-new.png Binary files differnew file mode 100644 index 0000000000..6d094d7b54 --- /dev/null +++ b/tests/auto/gui/image/qiconhighdpi/icons/testtheme/22x22@2/actions/appointment-new.png diff --git a/tests/auto/gui/image/qiconhighdpi/icons/testtheme/index.theme b/tests/auto/gui/image/qiconhighdpi/icons/testtheme/index.theme new file mode 100644 index 0000000000..6ab6c15c42 --- /dev/null +++ b/tests/auto/gui/image/qiconhighdpi/icons/testtheme/index.theme @@ -0,0 +1,21 @@ +[Icon Theme] +Name=Test +Comment=Test Theme + +Directories=16x16/actions,22x22/actions,22x22@2/actions + +[16x16/actions] +Size=16 +Context=Actions +Type=Fixed + +[22x22/actions] +Size=22 +Context=Actions +Type=Fixed + +[22x22@2/actions] +Size=22 +Context=Actions +Scale=2 +Type=Fixed diff --git a/tests/auto/gui/image/qiconhighdpi/qiconhighdpi.pro b/tests/auto/gui/image/qiconhighdpi/qiconhighdpi.pro new file mode 100644 index 0000000000..17553158bc --- /dev/null +++ b/tests/auto/gui/image/qiconhighdpi/qiconhighdpi.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +TARGET = tst_qicon + +QT += testlib +SOURCES += tst_qiconhighdpi.cpp +RESOURCES = tst_qiconhighdpi.qrc + +TESTDATA += icons/* diff --git a/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp b/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp new file mode 100644 index 0000000000..ce7f68a0a6 --- /dev/null +++ b/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.cpp @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <qicon.h> + +class tst_QIconHighDpi : public QObject +{ + Q_OBJECT +public: + tst_QIconHighDpi(); + +private slots: + void initTestCase(); + void fromTheme_data(); + void fromTheme(); +}; + +tst_QIconHighDpi::tst_QIconHighDpi() +{ +} + +void tst_QIconHighDpi::initTestCase() +{ +} + +void tst_QIconHighDpi::fromTheme_data() +{ + QTest::addColumn<int>("requestedSize"); + QTest::addColumn<int>("expectedSize"); + QTest::addColumn<qreal>("expectedDpr"); + + // The pixmaps that we have available can be found in tst_qiconhighdpi.qrc. + // Currently we only have @1 and @2 icons available. + const int dpr = qCeil(qApp->devicePixelRatio()); + + // We have an @2 high DPI version of the 22x22 size of this icon. + switch (dpr) { + case 1: QTest::newRow("22x22,dpr=1") << 22 << 22 << 1.0; break; + case 2: QTest::newRow("22x22,dpr=2") << 22 << 44 << 2.0; break; + case 3: QTest::newRow("22x22,dpr=3") << 22 << 44 << 2.0; break; + } + + // We don't have a high DPI version of the 16x16 size of this icon, + // so directoryMatchesSize() will return false for all directories. + // directorySizeDistance() is then called to find the best match. + // The table below illustrates the results for our available images at various DPRs: + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 16 * 1 = 28 + // 22 * 1 - 16 * 1 = 6 + // 16 * 1 - 16 * 1 = 0 < (16x16) + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 16 * 2 = 12 + // 22 * 1 - 16 * 2 = 10 < (22x22) + // 16 * 1 - 16 * 2 = 16 + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 16 * 3 = 4 < (22x22@2) + // 22 * 1 - 16 * 3 = 26 + // 16 * 1 - 16 * 3 = 32 + // Both of these functions are implementations of the freedesktop icon theme spec, + // which dictates that if there is no matching scale, directorySizeDistance() determines + // the winner, regardless of whether or not the scale is too low for the requested scale. + switch (dpr) { + case 1: QTest::newRow("16x16,dpr=1") << 16 << 16 << 1.0; break; + // PixmapEntry::pixmap() will only downscale the pixmap if actualSize.width() > size.width(). + // In this case, 22 > 32 is false, so a 22x22 pixmap is returned. + case 2: QTest::newRow("16x16,dpr=2") << 16 << 22 << 1.375; break; + case 3: QTest::newRow("16x16,dpr=3") << 16 << 44 << 2.75; break; + } + + // We don't have an 8x8 size of this icon, so: + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 8 * 1 = 36 + // 22 * 1 - 8 * 1 = 14 + // 16 * 1 - 8 * 1 = 8 < (16x16) + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 8 * 2 = 28 + // 22 * 1 - 8 * 2 = 6 + // 16 * 1 - 8 * 2 = 0 < (16x16) + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 8 * 3 = 20 + // 22 * 1 - 8 * 3 = 2 < (22x22) + // 16 * 1 - 8 * 3 = 8 + switch (dpr) { + case 1: QTest::newRow("8x8,dpr=1") << 8 << 8 << 1.0; break; + case 2: QTest::newRow("8x8,dpr=2") << 8 << 16 << 2.0; break; + case 3: QTest::newRow("8x8,dpr=3") << 8 << 22 << 2.75; break; + } + + // We don't have a 44x44 size of this icon, so: + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 44 * 1 = 0 < (22x22@2) + // 22 * 1 - 44 * 1 = 22 + // 16 * 1 - 44 * 1 = 28 + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 44 * 2 = 44 < (22x22@2) + // 22 * 1 - 44 * 2 = 66 + // 16 * 1 - 44 * 2 = 72 + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 44 * 3 = 88 < (22x22@2) + // 22 * 1 - 44 * 3 = 110 + // 16 * 1 - 44 * 3 = 116 + switch (dpr) { + case 1: QTest::newRow("44x44,dpr=1") << 44 << 44 << 1.0; break; + case 2: QTest::newRow("44x44,dpr=2") << 44 << 44 << 1.0; break; + case 3: QTest::newRow("44x44,dpr=3") << 44 << 44 << 1.0; break; + } + + // We don't have a 20x20 size of this icon, so: + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 20 * 1 = 24 + // 22 * 1 - 20 * 1 = 2 < (22x22) + // 16 * 1 - 20 * 1 = 4 + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 20 * 2 = 4 < (22x22@2) + // 22 * 1 - 20 * 2 = 18 + // 16 * 1 - 20 * 2 = 24 + // Available size | Available scale | Requested size | Requested scale | Distance + // 22 * 2 - 20 * 3 = 16 < (22x22@2) + // 22 * 1 - 20 * 3 = 38 + // 16 * 1 - 20 * 3 = 44 + switch (dpr) { + case 1: QTest::newRow("20x20,dpr=1") << 20 << 20 << 1.0; break; + // PixmapEntry::pixmap() will only downscale the pixmap if actualSize.width() > size.width(). + // In this case, 44 > 40 is true, so the 44x44 pixmap is downscaled to 40x40. + case 2: QTest::newRow("20x20,dpr=2") << 20 << 40 << 2.0; break; + case 3: QTest::newRow("20x20,dpr=3") << 20 << 44 << 2.2; break; + } +} + +void tst_QIconHighDpi::fromTheme() +{ + QFETCH(int, requestedSize); + QFETCH(int, expectedSize); + QFETCH(qreal, expectedDpr); + + QString searchPath = QLatin1String(":/icons"); + QIcon::setThemeSearchPaths(QStringList() << searchPath); + QCOMPARE(QIcon::themeSearchPaths().size(), 1); + QCOMPARE(searchPath, QIcon::themeSearchPaths()[0]); + + QString themeName("testtheme"); + QIcon::setThemeName(themeName); + QCOMPARE(QIcon::themeName(), themeName); + + QIcon appointmentIcon = QIcon::fromTheme("appointment-new"); + QVERIFY(!appointmentIcon.isNull()); + QVERIFY(!appointmentIcon.availableSizes(QIcon::Normal, QIcon::Off).isEmpty()); + QVERIFY(appointmentIcon.availableSizes().contains(QSize(16, 16))); + QVERIFY(appointmentIcon.availableSizes().contains(QSize(22, 22))); + + const QPixmap pixmap = appointmentIcon.pixmap(requestedSize); + QCOMPARE(pixmap.size(), QSize(expectedSize, expectedSize)); + // We should get the high DPI version of an image if it exists in the correct directory. + // Note that we didn't pass the QWindow to QIcon::pixmap(), + // because QGuiApplication::devicePixelRatio() will be used if no window was given. + QCOMPARE(pixmap.devicePixelRatio(), expectedDpr); +} + +int main(int argc, char *argv[]) +{ + QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + QGuiApplication app(argc, argv); + Q_UNUSED(app); + tst_QIconHighDpi test; + QTEST_SET_MAIN_SOURCE_PATH + return QTest::qExec(&test, argc, argv); +} + +#include "tst_qiconhighdpi.moc" diff --git a/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.qrc b/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.qrc new file mode 100644 index 0000000000..80b5e38ee6 --- /dev/null +++ b/tests/auto/gui/image/qiconhighdpi/tst_qiconhighdpi.qrc @@ -0,0 +1,8 @@ +<RCC> + <qresource prefix="/"> + <file>icons/testtheme/16x16/actions/appointment-new.png</file> + <file>icons/testtheme/22x22/actions/appointment-new.png</file> + <file>icons/testtheme/index.theme</file> + <file>icons/testtheme/22x22@2/actions/appointment-new.png</file> + </qresource> +</RCC> diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 2433fa4115..21481e374d 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -206,6 +206,11 @@ private slots: void ditherGradient_data(); void ditherGradient(); + void reinterpretAsFormat_data(); + void reinterpretAsFormat(); + + void reinterpretAsFormat2(); + #ifdef Q_OS_DARWIN void toCGImage_data(); void toCGImage(); @@ -1088,35 +1093,11 @@ void tst_QImage::rotate_data() degrees << 0 << 90 << 180 << 270; foreach (int d, degrees) { - const QByteArray dB = QByteArray::number(d); - QTest::newRow((dB + " Format_RGB32").constData()) - << QImage::Format_RGB32 << d; - QTest::newRow((dB + " Format_ARGB32").constData()) - << QImage::Format_ARGB32 << d; - QTest::newRow((dB + " Format_ARGB32_Premultiplied").constData()) - << QImage::Format_ARGB32_Premultiplied << d; - QTest::newRow((dB + " Format_RGB16").constData()) - << QImage::Format_RGB16 << d; - QTest::newRow((dB + " Format_ARGB8565_Premultiplied").constData()) - << QImage::Format_ARGB8565_Premultiplied << d; - QTest::newRow((dB + " Format_RGB666").constData()) - << QImage::Format_RGB666 << d; - QTest::newRow((dB + " Format_RGB555").constData()) - << QImage::Format_RGB555 << d; - QTest::newRow((dB + " Format_ARGB8555_Premultiplied").constData()) - << QImage::Format_ARGB8555_Premultiplied << d; - QTest::newRow((dB + " Format_RGB888").constData()) - << QImage::Format_RGB888 << d; - QTest::newRow((dB + " Format_Indexed8").constData()) - << QImage::Format_Indexed8 << d; - QTest::newRow((dB + " Format_RGBX8888").constData()) - << QImage::Format_RGBX8888 << d; - QTest::newRow((dB + " Format_RGBA8888_Premultiplied").constData()) - << QImage::Format_RGBA8888_Premultiplied << d; - QTest::newRow((dB + " Format_Alpha8").constData()) - << QImage::Format_Alpha8 << d; - QTest::newRow((dB + " Format_Grayscale8").constData()) - << QImage::Format_Grayscale8 << d; + const QString dB = QString::number(d); + for (int i = QImage::Format_Indexed8; i < QImage::NImageFormats; i++) { + QImage::Format format = static_cast<QImage::Format>(i); + QTest::newRow(qPrintable(dB + " " + formatToString(format))) << format << d; + } } } @@ -3327,6 +3308,64 @@ void tst_QImage::ditherGradient() QVERIFY(observedGradientSteps >= minimumExpectedGradient); } +void tst_QImage::reinterpretAsFormat_data() +{ + QTest::addColumn<QImage::Format>("in_format"); + QTest::addColumn<QImage::Format>("out_format"); + QTest::addColumn<QColor>("in_color"); + QTest::addColumn<QColor>("out_color"); + +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + QTest::newRow("rgb32 -> rgbx8888") << QImage::Format_RGB32 << QImage::Format_RGBX8888 << QColor(Qt::red) << QColor(Qt::blue); + QTest::newRow("rgba8888 -> argb32") << QImage::Format_RGBA8888 << QImage::Format_ARGB32 << QColor(Qt::red) << QColor(Qt::blue); + QTest::newRow("argb32pm -> rgba8888pm") << QImage::Format_RGBA8888_Premultiplied << QImage::Format_ARGB32_Premultiplied << QColor(Qt::green) << QColor(Qt::green); +#endif + QTest::newRow("rgb32 -> argb32") << QImage::Format_RGB32 << QImage::Format_ARGB32 << QColor(Qt::cyan) << QColor(Qt::cyan); + QTest::newRow("argb32pm -> rgb32") << QImage::Format_ARGB32_Premultiplied << QImage::Format_RGB32 << QColor(Qt::transparent) << QColor(Qt::black); + QTest::newRow("argb32 -> rgb32") << QImage::Format_ARGB32 << QImage::Format_RGB32 << QColor(255, 0, 0, 127) << QColor(255, 0, 0); + QTest::newRow("argb32pm -> rgb32") << QImage::Format_ARGB32_Premultiplied << QImage::Format_RGB32 << QColor(255, 0, 0, 127) << QColor(127, 0, 0); +} + +void tst_QImage::reinterpretAsFormat() +{ + QFETCH(QImage::Format, in_format); + QFETCH(QImage::Format, out_format); + QFETCH(QColor, in_color); + QFETCH(QColor, out_color); + + QImage image(1, 1, in_format); + image.setPixelColor(0, 0, in_color); + QVERIFY(image.reinterpretAsFormat(out_format)); + QCOMPARE(image.pixelColor(0, 0), out_color); +} + +void tst_QImage::reinterpretAsFormat2() +{ + const uint imageData[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + { + QImage image(reinterpret_cast<const uchar*>(imageData), 4, 2, QImage::Format_RGB32); + QCOMPARE(image.pixelColor(0, 0), QColor(Qt::black)); + QVERIFY(image.isDetached()); + QVERIFY(image.reinterpretAsFormat(QImage::Format_ARGB32_Premultiplied)); + QCOMPARE(image.constBits(), reinterpret_cast<const uchar*>(imageData)); + QCOMPARE(image.pixelColor(0, 0), QColor(Qt::transparent)); + + QVERIFY(!image.reinterpretAsFormat(QImage::Format_Grayscale8)); + } + { + QImage image(reinterpret_cast<const uchar*>(imageData), 8, 4, QImage::Format_Indexed8); + image.setColor(0, qRgb(255, 255, 255)); + QCOMPARE(image.pixelColor(0, 0), QColor(Qt::white)); + QVERIFY(image.reinterpretAsFormat(QImage::Format_Grayscale8)); + QCOMPARE(image.pixelColor(0, 0), QColor(Qt::black)); + QVERIFY(image.reinterpretAsFormat(QImage::Format_Alpha8)); + QCOMPARE(image.pixelColor(0, 0), QColor(Qt::transparent)); + + QVERIFY(!image.reinterpretAsFormat(QImage::Format_RGB16)); + } +} + #ifdef Q_OS_DARWIN void tst_QImage::toCGImage_data() diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index bd02dc6255..18649b3de5 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -133,6 +133,9 @@ private slots: void gifImageCount(); void gifLoopCount(); + void ppmMaxval_data(); + void ppmMaxval(); + void readCorruptImage_data(); void readCorruptImage(); void readCorruptBmp(); @@ -956,6 +959,79 @@ void tst_QImageReader::gifLoopCount() } } +void tst_QImageReader::ppmMaxval_data() +{ + QTest::addColumn<bool>("hasColor"); + QTest::addColumn<QByteArray>("bytes"); + + QTest::newRow("PGM plain 8bit full") << false << QByteArray("P2 3 1 255 255 0 127\n"); + QTest::newRow("PGM plain 8bit lim.") << false << QByteArray("P2 3 1 50 50 0 25\n"); + QTest::newRow("PGM plain 16bit full") << false << QByteArray("P2 3 1 65535 65535 0 32767\n"); + QTest::newRow("PGM plain 16bit lim.") << false << QByteArray("P2 3 1 5000 5000 0 2500\n"); + QTest::newRow("PGM raw 8bit full") << false << QByteArray("P5 3 1 255 \xff\x00\x7f", 13 + 3); + QTest::newRow("PGM raw 8bit lim.") << false << QByteArray("P5 3 1 50 \x32\x00\x19", 13 + 3); + QTest::newRow("PGM raw 16bit full") << false << QByteArray("P5 3 1 65535 \xff\xff\x00\x00\x7f\xff", 13 + 3 * 2); + QTest::newRow("PGM raw 16bit lim.") << false << QByteArray("P5 3 1 5000 \x13\x88\x00\x00\x09\xc4", 13 + 3 * 2); + + QTest::newRow("PPM plain 8bit full") << true << QByteArray("P3 3 2 255 " + "255 255 255 0 0 0 127 127 127 " + "255 0 0 0 255 0 0 0 255\n"); + + QTest::newRow("PPM plain 8bit lim.") << true << QByteArray("P3 3 2 50 " + " 50 50 50 0 0 0 25 25 25 " + " 50 0 0 0 50 0 0 0 50\n"); + + QTest::newRow("PPM plain 16bit full") << true << QByteArray("P3 3 2 65535 " + "65535 65535 65535 0 0 0 32767 32767 32767 " + "65535 0 0 0 65535 0 0 0 65535\n"); + + QTest::newRow("PPM plain 16bit lim.") << true << QByteArray("P3 3 2 5000 " + " 5000 5000 5000 0 0 0 2500 2500 2500 " + " 5000 0 0 0 5000 0 0 0 5000\n"); + + QTest::newRow("PPM raw 8bit full") << true << QByteArray("P6 3 2 255 " + "\xff\xff\xff\x00\x00\x00\x7f\x7f\x7f" + "\xff\x00\x00\x00\xff\x00\x00\x00\xff", 13 + 6 * 3); + + QTest::newRow("PPM raw 8bit lim.") << true << QByteArray("P6 3 2 50 " + "\x32\x32\x32\x00\x00\x00\x19\x19\x19" + "\x32\x00\x00\x00\x32\x00\x00\x00\x32", 13 + 6 * 3); + + QTest::newRow("PPM raw 16bit full") << true << QByteArray("P6 3 2 65535 " + "\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x7f\xff\x7f\xff\x7f\xff" + "\xff\xff\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\xff\xff", 13 + 6 * 3 * 2); + + QTest::newRow("PPM raw 16bit lim.") << true << QByteArray("P6 3 2 5000 " + "\x13\x88\x13\x88\x13\x88\x00\x00\x00\x00\x00\x00\x09\xc4\x09\xc4\x09\xc4" + "\x13\x88\x00\x00\x00\x00\x00\x00\x13\x88\x00\x00\x00\x00\x00\x00\x13\x88", 13 + 6 * 3 * 2); +} + +void tst_QImageReader::ppmMaxval() +{ + SKIP_IF_UNSUPPORTED("ppm"); + + QFETCH(bool, hasColor); + QFETCH(QByteArray, bytes); + + QImage img; + img.loadFromData(bytes); + QVERIFY(!img.isNull()); + QCOMPARE(img.width(), 3); + QCOMPARE(img.height(), hasColor ? 2 : 1); + + QCOMPARE(img.pixel(0,0), qRgb(0xff, 0xff, 0xff)); + QCOMPARE(img.pixel(1,0), qRgb(0, 0, 0)); + QRgb gray = img.pixel(2,0); + QVERIFY(qIsGray(gray)); + QVERIFY(qRed(gray) > 0x70 && qRed(gray) < 0x90 ); + + if (hasColor) { + QCOMPARE(img.pixel(0,1), qRgb(0xff, 0, 0)); + QCOMPARE(img.pixel(1,1), qRgb(0, 0xff, 0)); + QCOMPARE(img.pixel(2,1), qRgb(0, 0, 0xff)); + } +} + class Server : public QObject { Q_OBJECT diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index 191aabdf6a..d5c624833c 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -47,7 +47,7 @@ #include <algorithm> typedef QMap<QString, QString> QStringMap; -typedef QList<int> QIntList; +typedef QVector<int> QIntList; Q_DECLARE_METATYPE(QImageWriter::ImageWriterError) Q_DECLARE_METATYPE(QImage::Format) @@ -227,8 +227,15 @@ void tst_QImageWriter::writeImage2_data() QTest::addColumn<QByteArray>("format"); QTest::addColumn<QImage>("image"); - const QStringList formats = QStringList() << "bmp" << "xpm" << "png" - << "ppm" << "ico"; //<< "jpeg"; + static const QLatin1String formats[] = { + QLatin1String("bmp"), + QLatin1String("xpm"), + QLatin1String("png"), + QLatin1String("ppm"), + QLatin1String("ico"), + // QLatin1String("jpeg"), + }; + QImage image0(70, 70, QImage::Format_ARGB32); image0.fill(QColor(Qt::red).rgb()); @@ -236,11 +243,11 @@ void tst_QImageWriter::writeImage2_data() while (imgFormat != QImage::NImageFormats) { QImage image = image0.convertToFormat(imgFormat); initializePadding(&image); - foreach (const QString format, formats) { + for (QLatin1String format : formats) { const QString fileName = QLatin1String("solidcolor_") + QString::number(imgFormat) + QLatin1Char('.') + format; QTest::newRow(fileName.toLatin1()) << writePrefix + fileName - << format.toLatin1() + << QByteArray(format.data(), format.size()) << image; } imgFormat = QImage::Format(int(imgFormat) + 1); @@ -304,41 +311,38 @@ void tst_QImageWriter::writeImage2() QVERIFY(QFile::remove(fileName)); } +namespace { +// C++98-library version of C++11 std::is_sorted +template <typename C> +bool is_sorted(const C &c) +{ + return std::adjacent_find(c.begin(), c.end(), std::greater_equal<typename C::value_type>()) == c.end(); +} +} + void tst_QImageWriter::supportedFormats() { QList<QByteArray> formats = QImageWriter::supportedImageFormats(); - QList<QByteArray> sortedFormats = formats; - std::sort(sortedFormats.begin(), sortedFormats.end()); // check that the list is sorted - QCOMPARE(formats, sortedFormats); - - QSet<QByteArray> formatSet; - foreach (QByteArray format, formats) - formatSet << format; + QVERIFY(is_sorted(formats)); // check that the list does not contain duplicates - QCOMPARE(formatSet.size(), formats.size()); + QVERIFY(std::unique(formats.begin(), formats.end()) == formats.end()); } void tst_QImageWriter::supportedMimeTypes() { QList<QByteArray> mimeTypes = QImageWriter::supportedMimeTypes(); - QList<QByteArray> sortedMimeTypes = mimeTypes; - std::sort(sortedMimeTypes.begin(), sortedMimeTypes.end()); // check that the list is sorted - QCOMPARE(mimeTypes, sortedMimeTypes); - - QSet<QByteArray> mimeTypeSet; - foreach (QByteArray mimeType, mimeTypes) - mimeTypeSet << mimeType; + QVERIFY(is_sorted(mimeTypes)); // check the list as a minimum contains image/bmp - QVERIFY(mimeTypeSet.contains("image/bmp")); + QVERIFY(mimeTypes.contains("image/bmp")); // check that the list does not contain duplicates - QCOMPARE(mimeTypeSet.size(), mimeTypes.size()); + QVERIFY(std::unique(mimeTypes.begin(), mimeTypes.end()) == mimeTypes.end()); } void tst_QImageWriter::writeToInvalidDevice() @@ -412,30 +416,27 @@ void tst_QImageWriter::supportsOption() QFETCH(QString, fileName); QFETCH(QIntList, options); - QSet<QImageIOHandler::ImageOption> allOptions; - allOptions << QImageIOHandler::Size - << QImageIOHandler::ClipRect - << QImageIOHandler::Description - << QImageIOHandler::ScaledClipRect - << QImageIOHandler::ScaledSize - << QImageIOHandler::CompressionRatio - << QImageIOHandler::Gamma - << QImageIOHandler::Quality - << QImageIOHandler::Name - << QImageIOHandler::SubType - << QImageIOHandler::IncrementalReading - << QImageIOHandler::Endianness - << QImageIOHandler::Animation - << QImageIOHandler::BackgroundColor; + static Q_CONSTEXPR QImageIOHandler::ImageOption allOptions[] = { + QImageIOHandler::Size, + QImageIOHandler::ClipRect, + QImageIOHandler::Description, + QImageIOHandler::ScaledClipRect, + QImageIOHandler::ScaledSize, + QImageIOHandler::CompressionRatio, + QImageIOHandler::Gamma, + QImageIOHandler::Quality, + QImageIOHandler::Name, + QImageIOHandler::SubType, + QImageIOHandler::IncrementalReading, + QImageIOHandler::Endianness, + QImageIOHandler::Animation, + QImageIOHandler::BackgroundColor, + }; QImageWriter writer(writePrefix + fileName); - for (int i = 0; i < options.size(); ++i) { - QVERIFY(writer.supportsOption(QImageIOHandler::ImageOption(options.at(i)))); - allOptions.remove(QImageIOHandler::ImageOption(options.at(i))); + for (auto option : allOptions) { + QCOMPARE(writer.supportsOption(option), options.contains(option)); } - - foreach (QImageIOHandler::ImageOption option, allOptions) - QVERIFY(!writer.supportsOption(option)); } void tst_QImageWriter::saveWithNoFormat_data() diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index ad7de09c48..e3bda6c2df 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -99,6 +99,7 @@ private slots: void task_51271(); void convertFromImageNoDetach(); + void convertFromImageNoDetach2(); void convertFromImageDetach(); void convertFromImageCacheKey(); @@ -118,6 +119,7 @@ private slots: void refUnref(); void copy(); + void deepCopyPreservesDpr(); void depthOfNullObjects(); void transformed(); @@ -766,6 +768,33 @@ void tst_QPixmap::convertFromImageNoDetach() QCOMPARE(constOrig.bits(), constCopy.bits()); } +void tst_QPixmap::convertFromImageNoDetach2() +{ + QPixmap randomPixmap(10, 10); + if (randomPixmap.handle()->classId() != QPlatformPixmap::RasterClass) + QSKIP("Test only valid for raster pixmaps"); + + //first get the screen format + QImage::Format screenFormat = randomPixmap.toImage().format(); + QVERIFY(screenFormat != QImage::Format_Invalid); + if (screenFormat != QImage::Format_RGB32 && + screenFormat != QImage::Format_ARGB32_Premultiplied) + QSKIP("Test only valid for platforms with RGB32 pixmaps"); + + QImage orig(100,100, QImage::Format_ARGB32_Premultiplied); + orig.fill(Qt::white); + + const uchar *origBits = orig.constBits(); + + QPixmap pix = QPixmap::fromImage(std::move(orig)); + QImage copy = pix.toImage(); + + QVERIFY(!copy.hasAlphaChannel()); + QCOMPARE(copy.format(), QImage::Format_RGB32); + + QCOMPARE(origBits, copy.constBits()); +} + void tst_QPixmap::convertFromImageDetach() { QImage img(10,10, QImage::Format_RGB32); @@ -1105,6 +1134,19 @@ void tst_QPixmap::copy() QCOMPARE(trans, transCopy); } +// QTBUG-58653: Force a deep copy of a pixmap by +// having a QPainter and check whether DevicePixelRatio is preserved +void tst_QPixmap::deepCopyPreservesDpr() +{ + const qreal dpr = 2; + QPixmap src(32, 32); + src.setDevicePixelRatio(dpr); + src.fill(Qt::red); + QPainter painter(&src); + const QPixmap dest = src.copy(); + QCOMPARE(dest.devicePixelRatio(), dpr); +} + void tst_QPixmap::depthOfNullObjects() { QBitmap b1; diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index f8bcb14ab3..a935258fb8 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -70,6 +70,8 @@ private slots: void palette(); void modalWindow(); void quitOnLastWindowClosed(); + void quitOnLastWindowClosedMulti(); + void dontQuitOnLastWindowClosed(); void genericPluginsAndWindowSystemEvents(); void layoutDirection(); void globalShareContext(); @@ -791,107 +793,111 @@ void tst_QGuiApplication::modalWindow() void tst_QGuiApplication::quitOnLastWindowClosed() { - { - int argc = 0; - QGuiApplication app(argc, 0); - const QRect screenGeometry = QGuiApplication::primaryScreen()->availableVirtualGeometry(); + int argc = 0; + QGuiApplication app(argc, 0); + const QRect screenGeometry = QGuiApplication::primaryScreen()->availableVirtualGeometry(); - QTimer timer; - timer.setInterval(100); + QTimer timer; + timer.setInterval(100); - QSignalSpy spy(&app, SIGNAL(aboutToQuit())); - QSignalSpy spy2(&timer, SIGNAL(timeout())); + QSignalSpy spyAboutToQuit(&app, &QCoreApplication::aboutToQuit); + QSignalSpy spyTimeout(&timer, &QTimer::timeout); - QWindow mainWindow; - mainWindow.setTitle(QStringLiteral("quitOnLastWindowClosedMainWindow")); - mainWindow.resize(windowSize, windowSize); - mainWindow.setFramePosition(QPoint(screenGeometry.left() + spacing, screenGeometry.top() + spacing)); + QWindow mainWindow; + mainWindow.setTitle(QStringLiteral("quitOnLastWindowClosedMainWindow")); + mainWindow.resize(windowSize, windowSize); + mainWindow.setFramePosition(QPoint(screenGeometry.left() + spacing, screenGeometry.top() + spacing)); - QWindow dialog; - dialog.setTransientParent(&mainWindow); - dialog.setTitle(QStringLiteral("quitOnLastWindowClosedDialog")); - dialog.resize(windowSize, windowSize); - dialog.setFramePosition(QPoint(screenGeometry.left() + 2 * spacing + windowSize, screenGeometry.top() + spacing)); + QWindow dialog; + dialog.setTransientParent(&mainWindow); + dialog.setTitle(QStringLiteral("quitOnLastWindowClosedDialog")); + dialog.resize(windowSize, windowSize); + dialog.setFramePosition(QPoint(screenGeometry.left() + 2 * spacing + windowSize, screenGeometry.top() + spacing)); - QVERIFY(app.quitOnLastWindowClosed()); + QVERIFY(app.quitOnLastWindowClosed()); - mainWindow.show(); - dialog.show(); - QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + mainWindow.show(); + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); - timer.start(); - QTimer::singleShot(1000, &mainWindow, SLOT(close())); // This should quit the application - QTimer::singleShot(2000, &app, SLOT(quit())); // This makes sure we quit even if it didn't + timer.start(); + QTimer::singleShot(1000, &mainWindow, &QWindow::close); // This should quit the application + QTimer::singleShot(2000, &app, QCoreApplication::quit); // This makes sure we quit even if it didn't - app.exec(); + app.exec(); - QCOMPARE(spy.count(), 1); - QVERIFY(spy2.count() < 15); // Should be around 10 if closing caused the quit - } - { - int argc = 0; - QGuiApplication app(argc, 0); - const QRect screenGeometry = QGuiApplication::primaryScreen()->availableVirtualGeometry(); + QCOMPARE(spyAboutToQuit.count(), 1); + // Should be around 10 if closing caused the quit + QVERIFY2(spyTimeout.count() < 15, QByteArray::number(spyTimeout.count()).constData()); +} - QTimer timer; - timer.setInterval(100); +void tst_QGuiApplication::quitOnLastWindowClosedMulti() +{ + int argc = 0; + QGuiApplication app(argc, 0); + const QRect screenGeometry = QGuiApplication::primaryScreen()->availableVirtualGeometry(); - QSignalSpy spy(&app, SIGNAL(aboutToQuit())); - QSignalSpy spy2(&timer, SIGNAL(timeout())); + QTimer timer; + timer.setInterval(100); - QWindow mainWindow; - mainWindow.setTitle(QStringLiteral("quitOnLastWindowClosedMainWindow")); - mainWindow.resize(windowSize, windowSize); - mainWindow.setFramePosition(QPoint(screenGeometry.left() + spacing, screenGeometry.top() + spacing)); + QSignalSpy spyAboutToQuit(&app, &QCoreApplication::aboutToQuit); + QSignalSpy spyTimeout(&timer, &QTimer::timeout); - QWindow dialog; - dialog.setTitle(QStringLiteral("quitOnLastWindowClosedDialog")); - dialog.resize(windowSize, windowSize); - dialog.setFramePosition(QPoint(screenGeometry.left() + 2 * spacing + windowSize, screenGeometry.top() + spacing)); + QWindow mainWindow; + mainWindow.setTitle(QStringLiteral("quitOnLastWindowClosedMultiMainWindow")); + mainWindow.resize(windowSize, windowSize); + mainWindow.setFramePosition(QPoint(screenGeometry.left() + spacing, screenGeometry.top() + spacing)); - QVERIFY(!dialog.transientParent()); - QVERIFY(app.quitOnLastWindowClosed()); + QWindow dialog; + dialog.setTitle(QStringLiteral("quitOnLastWindowClosedMultiDialog")); + dialog.resize(windowSize, windowSize); + dialog.setFramePosition(QPoint(screenGeometry.left() + 2 * spacing + windowSize, screenGeometry.top() + spacing)); - mainWindow.show(); - dialog.show(); - QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + QVERIFY(!dialog.transientParent()); + QVERIFY(app.quitOnLastWindowClosed()); - timer.start(); - QTimer::singleShot(1000, &mainWindow, SLOT(close())); // This should not quit the application - QTimer::singleShot(2000, &app, SLOT(quit())); + mainWindow.show(); + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); - app.exec(); + timer.start(); + QTimer::singleShot(1000, &mainWindow, &QWindow::close); // This should not quit the application + QTimer::singleShot(2000, &app, &QCoreApplication::quit); - QCOMPARE(spy.count(), 1); - QVERIFY(spy2.count() > 15); // Should be around 20 if closing did not cause the quit - } - { - int argc = 0; - QGuiApplication app(argc, 0); - app.setQuitOnLastWindowClosed(false); + app.exec(); + + QCOMPARE(spyAboutToQuit.count(), 1); + // Should be around 20 if closing did not cause the quit + QVERIFY2(spyTimeout.count() > 15, QByteArray::number(spyTimeout.count()).constData()); +} + +void tst_QGuiApplication::dontQuitOnLastWindowClosed() +{ + int argc = 0; + QGuiApplication app(argc, 0); + app.setQuitOnLastWindowClosed(false); - QTimer timer; - timer.setInterval(2000); - timer.setSingleShot(true); - QObject::connect(&timer, SIGNAL(timeout()), &app, SLOT(quit())); + QTimer timer; + timer.setInterval(2000); + timer.setSingleShot(true); + QObject::connect(&timer, &QTimer::timeout, &app, &QCoreApplication::quit); - QSignalSpy spy(&app, SIGNAL(lastWindowClosed())); - QSignalSpy spy2(&timer, SIGNAL(timeout())); + QSignalSpy spyLastWindowClosed(&app, &QGuiApplication::lastWindowClosed); + QSignalSpy spyTimeout(&timer, &QTimer::timeout); - QPointer<QWindow> mainWindow = new QWindow; + QScopedPointer<QWindow> mainWindow(new QWindow); - mainWindow->show(); + mainWindow->show(); - QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should not quit the application - timer.start(); + QTimer::singleShot(1000, mainWindow.data(), &QWindow::close); // This should not quit the application + timer.start(); - app.exec(); + app.exec(); - QCOMPARE(spy2.count(), 1); // quit timer fired - QCOMPARE(spy.count(), 1); // lastWindowClosed emitted + app.setQuitOnLastWindowClosed(true); // restore underlying static to default value - app.setQuitOnLastWindowClosed(true); // restore underlying static to default value - } + QCOMPARE(spyTimeout.count(), 1); // quit timer fired + QCOMPARE(spyLastWindowClosed.count(), 1); // lastWindowClosed emitted } static Qt::ScreenOrientation testOrientationToSend = Qt::PrimaryOrientation; diff --git a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp index 811a6d111f..bad021c3b0 100644 --- a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp +++ b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp @@ -1,31 +1,26 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp b/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp index b130210447..58dee6f6ca 100644 --- a/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp +++ b/tests/auto/gui/kernel/qopenglwindow/tst_qopenglwindow.cpp @@ -31,12 +31,15 @@ #include <QtGui/QOpenGLFunctions> #include <QtGui/QOpenGLContext> #include <QtGui/QPainter> +#include <private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> class tst_QOpenGLWindow : public QObject { Q_OBJECT private slots: + void initTestCase(); void create(); void basic(); void painter(); @@ -45,6 +48,12 @@ private slots: void underOver(); }; +void tst_QOpenGLWindow::initTestCase() +{ + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) + QSKIP("OpenGL is not supported on this platform."); +} + void tst_QOpenGLWindow::create() { QOpenGLWindow w; diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index 364b9332af..ec143896ab 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -36,6 +36,7 @@ #include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface_p.h> #include <private/qhighdpiscaling_p.h> +#include <private/qtouchdevice_p.h> class tst_QTouchEventWidget : public QWidget { @@ -200,6 +201,7 @@ private slots: void touchBeginPropagatesWhenIgnored(); void touchUpdateAndEndNeverPropagate(); void basicRawEventTranslation(); + void basicRawEventTranslationOfIds(); void multiPointRawEventTranslationOnTouchScreen(); void multiPointRawEventTranslationOnTouchPad(); void deleteInEventHandler(); @@ -641,7 +643,8 @@ void tst_QTouchEvent::basicRawEventTranslation() QCOMPARE(touchWidget.touchBeginPoints.count(), 1); QCOMPARE(touchWidget.timestamp, timestamp); QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first(); - QCOMPARE(touchBeginPoint.id(), rawTouchPoint.id()); + const int touchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1; + QCOMPARE(touchBeginPoint.id(), touchPointId); QCOMPARE(touchBeginPoint.state(), rawTouchPoint.state()); QCOMPARE(touchBeginPoint.pos(), pos); QCOMPARE(touchBeginPoint.startPos(), pos); @@ -676,7 +679,7 @@ void tst_QTouchEvent::basicRawEventTranslation() QVERIFY(!touchWidget.seenTouchEnd); QCOMPARE(touchWidget.touchUpdatePoints.count(), 1); QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first(); - QCOMPARE(touchUpdatePoint.id(), rawTouchPoint.id()); + QCOMPARE(touchUpdatePoint.id(), touchPointId); QCOMPARE(touchUpdatePoint.state(), rawTouchPoint.state()); QCOMPARE(touchUpdatePoint.pos(), pos + delta); QCOMPARE(touchUpdatePoint.startPos(), pos); @@ -708,7 +711,7 @@ void tst_QTouchEvent::basicRawEventTranslation() QVERIFY(touchWidget.seenTouchEnd); QCOMPARE(touchWidget.touchEndPoints.count(), 1); QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first(); - QCOMPARE(touchEndPoint.id(), rawTouchPoint.id()); + QCOMPARE(touchEndPoint.id(), touchPointId); QCOMPARE(touchEndPoint.state(), rawTouchPoint.state()); QCOMPARE(touchEndPoint.pos(), pos + delta + delta); QCOMPARE(touchEndPoint.startPos(), pos); @@ -784,9 +787,11 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() QVERIFY(!rightWidget.seenTouchEnd); QCOMPARE(leftWidget.touchBeginPoints.count(), 1); QCOMPARE(rightWidget.touchBeginPoints.count(), 1); + const int touchPointId0 = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1; + const int touchPointId1 = touchPointId0 + 1; { QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchBeginPoints.first(); - QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id()); + QCOMPARE(leftTouchPoint.id(), touchPointId0); QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state()); QCOMPARE(leftTouchPoint.pos(), leftPos); QCOMPARE(leftTouchPoint.startPos(), leftPos); @@ -806,7 +811,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() QCOMPARE(leftTouchPoint.pressure(), qreal(1.)); QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchBeginPoints.first(); - QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id()); + QCOMPARE(rightTouchPoint.id(), touchPointId1); QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state()); QCOMPARE(rightTouchPoint.pos(), rightPos); QCOMPARE(rightTouchPoint.startPos(), rightPos); @@ -850,7 +855,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() QCOMPARE(rightWidget.touchUpdatePoints.count(), 1); { QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchUpdatePoints.first(); - QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id()); + QCOMPARE(leftTouchPoint.id(), touchPointId0); QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state()); QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint()))); QCOMPARE(leftTouchPoint.startPos(), leftPos); @@ -870,7 +875,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() QCOMPARE(leftTouchPoint.pressure(), qreal(1.)); QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchUpdatePoints.first(); - QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id()); + QCOMPARE(rightTouchPoint.id(), touchPointId1); QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state()); QCOMPARE(rightTouchPoint.pos(), QPointF(rightWidget.mapFromParent(centerPos.toPoint()))); QCOMPARE(rightTouchPoint.startPos(), rightPos); @@ -914,7 +919,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() QCOMPARE(rightWidget.touchEndPoints.count(), 1); { QTouchEvent::TouchPoint leftTouchPoint = leftWidget.touchEndPoints.first(); - QCOMPARE(leftTouchPoint.id(), rawTouchPoints[0].id()); + QCOMPARE(leftTouchPoint.id(), touchPointId0); QCOMPARE(leftTouchPoint.state(), rawTouchPoints[0].state()); QCOMPARE(leftTouchPoint.pos(), QPointF(leftWidget.mapFromParent(centerPos.toPoint()))); QCOMPARE(leftTouchPoint.startPos(), leftPos); @@ -934,7 +939,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() QCOMPARE(leftTouchPoint.pressure(), qreal(0.)); QTouchEvent::TouchPoint rightTouchPoint = rightWidget.touchEndPoints.first(); - QCOMPARE(rightTouchPoint.id(), rawTouchPoints[1].id()); + QCOMPARE(rightTouchPoint.id(), touchPointId1); QCOMPARE(rightTouchPoint.state(), rawTouchPoints[1].state()); QCOMPARE(rightTouchPoint.pos(), QPointF(rightWidget.mapFromParent(centerPos.toPoint()))); QCOMPARE(rightTouchPoint.startPos(), rightPos); @@ -1184,6 +1189,126 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() } } +void tst_QTouchEvent::basicRawEventTranslationOfIds() +{ + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) + QSKIP("Wayland: This fails. Figure out why."); + + tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); + touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); + touchWidget.setGeometry(100, 100, 400, 300); + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); + + QVarLengthArray<QPointF, 2> pos; + QVarLengthArray<QPointF, 2> screenPos; + for (int i = 0; i < 2; ++i) { + pos << touchWidget.rect().center() + QPointF(20*i, 20*i); + screenPos << touchWidget.mapToGlobal(pos[i].toPoint()); + } + QPointF delta(10, 10); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); + + QVector<QPointF> rawPosList; + rawPosList << QPointF(12, 34) << QPointF(56, 78); + + QList<QTouchEvent::TouchPoint> rawTouchPoints; + + // Press both points, this should be translated to a TouchBegin + for (int i = 0; i < 2; ++i) { + QTouchEvent::TouchPoint rawTouchPoint; + rawTouchPoint.setId(i); + rawTouchPoint.setState(Qt::TouchPointPressed); + rawTouchPoint.setScreenPos(screenPos[i]); + rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry)); + rawTouchPoint.setRawScreenPositions(rawPosList); + rawTouchPoints << rawTouchPoint; + } + QTouchEvent::TouchPoint &p0 = rawTouchPoints[0]; + QTouchEvent::TouchPoint &p1 = rawTouchPoints[1]; + + const ulong timestamp = 1234; + QWindow *window = touchWidget.windowHandle(); + QList<QWindowSystemInterface::TouchPoint> nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, timestamp, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(!touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchBeginPoints.count(), 2); + + const int initialTouchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1; + + for (int i = 0; i < touchWidget.touchBeginPoints.count(); ++i) { + QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.at(i); + QCOMPARE(touchBeginPoint.id(), initialTouchPointId + i); + QCOMPARE(touchBeginPoint.state(), rawTouchPoints[i].state()); + } + + // moving the point should translate to TouchUpdate + for (int i = 0; i < rawTouchPoints.count(); ++i) { + QTouchEvent::TouchPoint &p = rawTouchPoints[i]; + p.setState(Qt::TouchPointMoved); + p.setScreenPos(p.screenPos() + delta); + p.setNormalizedPos(normalized(p.pos(), screenGeometry)); + } + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchUpdatePoints.count(), 2); + QCOMPARE(touchWidget.touchUpdatePoints.at(0).id(), initialTouchPointId); + QCOMPARE(touchWidget.touchUpdatePoints.at(1).id(), initialTouchPointId + 1); + + // release last point + p0.setState(Qt::TouchPointStationary); + p1.setState(Qt::TouchPointReleased); + + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchUpdatePoints.count(), 2); + QCOMPARE(touchWidget.touchUpdatePoints[0].id(), initialTouchPointId); + QCOMPARE(touchWidget.touchUpdatePoints[1].id(), initialTouchPointId + 1); + + // Press last point again, id should increase + p1.setState(Qt::TouchPointPressed); + p1.setId(42); // new id + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchUpdatePoints.count(), 2); + QCOMPARE(touchWidget.touchUpdatePoints[0].id(), initialTouchPointId); + QCOMPARE(touchWidget.touchUpdatePoints[1].id(), initialTouchPointId + 2); + + // release everything + p0.setState(Qt::TouchPointReleased); + p1.setState(Qt::TouchPointReleased); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(rawTouchPoints, window); + QWindowSystemInterface::handleTouchEvent(window, 0, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchUpdatePoints.count(), 2); + QCOMPARE(touchWidget.touchUpdatePoints[0].id(), initialTouchPointId); + QCOMPARE(touchWidget.touchUpdatePoints[1].id(), initialTouchPointId + 2); +} + void tst_QTouchEvent::deleteInEventHandler() { if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 6ec0268d96..36ec28de8d 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -56,6 +56,7 @@ private slots: void create(); void setParent(); void setVisible(); + void setVisibleFalseDoesNotCreateWindow(); void eventOrderOnShow(); void resizeEventAfterResize(); void exposeEventOnShrink_QTBUG54040(); @@ -65,6 +66,7 @@ private slots: void positioningDuringMinimized(); void childWindowPositioning_data(); void childWindowPositioning(); + void childWindowLevel(); void platformSurface(); void isExposed(); void isActive(); @@ -101,6 +103,7 @@ private slots: void initTestCase(); void stateChange_data(); void stateChange(); + void flags(); void cleanup(); private: @@ -232,6 +235,16 @@ void tst_QWindow::setVisible() QVERIFY(QTest::qWaitForWindowExposed(&i)); } +void tst_QWindow::setVisibleFalseDoesNotCreateWindow() +{ + QWindow w; + QVERIFY(!w.handle()); + w.setVisible(false); + QVERIFY2(!w.handle(), "Hiding a non-created window doesn't create it"); + w.setVisible(true); + QVERIFY2(w.handle(), "Showing a non-created window creates it"); +} + void tst_QWindow::mapGlobal() { QWindow a; @@ -596,6 +609,29 @@ void tst_QWindow::childWindowPositioning() QCOMPARE(childWindowAfter.framePosition(), topLeftOrigin); } +void tst_QWindow::childWindowLevel() +{ + ColoredWindow topLevel(Qt::green); + topLevel.setObjectName("topLevel"); + ColoredWindow yellowChild(Qt::yellow, &topLevel); + yellowChild.setObjectName("yellowChild"); + ColoredWindow redChild(Qt::red, &topLevel); + redChild.setObjectName("redChild"); + ColoredWindow blueChild(Qt::blue, &topLevel); + blueChild.setObjectName("blueChild"); + + const QObjectList &siblings = topLevel.children(); + + QCOMPARE(siblings.constFirst(), &yellowChild); + QCOMPARE(siblings.constLast(), &blueChild); + + yellowChild.raise(); + QCOMPARE(siblings.constLast(), &yellowChild); + + blueChild.lower(); + QCOMPARE(siblings.constFirst(), &blueChild); +} + // QTBUG-49709: Verify that the normal geometry is correctly restored // when executing a sequence of window state changes. So far, Windows // only where state changes have immediate effect. @@ -2170,6 +2206,18 @@ void tst_QWindow::requestUpdate() QTRY_COMPARE(window.received(QEvent::UpdateRequest), 2); } +void tst_QWindow::flags() +{ + Window window; + const auto baseFlags = window.flags(); + window.setFlags(window.flags() | Qt::FramelessWindowHint); + QCOMPARE(window.flags(), baseFlags | Qt::FramelessWindowHint); + window.setFlag(Qt::WindowStaysOnTopHint, true); + QCOMPARE(window.flags(), baseFlags | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + window.setFlag(Qt::FramelessWindowHint, false); + QCOMPARE(window.flags(), baseFlags | Qt::WindowStaysOnTopHint); +} + #include <tst_qwindow.moc> QTEST_MAIN(tst_QWindow) diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index 9dd9ab05e8..1ce7e797fc 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -33,6 +33,7 @@ #include <qcolor.h> #include <qdebug.h> +#include <private/qcolorprofile_p.h> #include <private/qdrawingprimitive_sse2_p.h> #include <qrgba64.h> @@ -107,6 +108,9 @@ private slots: void qrgba64Premultiply(); void qrgba64Equivalence(); + void qcolorprofile_data(); + void qcolorprofile(); + #if 0 // Used to be included in Qt4 for Q_WS_X11 void setallowX11ColorNames(); #endif @@ -1587,5 +1591,36 @@ void tst_QColor::qrgba64Equivalence() } } +void tst_QColor::qcolorprofile_data() +{ + QTest::addColumn<qreal>("gammaC"); + QTest::addColumn<int>("tolerance"); + + QTest::newRow("gamma=1.0") << qreal(1.0) << 0; + QTest::newRow("gamma=1.5") << qreal(1.5) << 1; + QTest::newRow("gamma=1.7") << qreal(1.7) << 2; + QTest::newRow("gamma=2.0") << qreal(2.0) << 8; + QTest::newRow("gamma=2.31") << qreal(2.31) << 33; + QTest::newRow("SRgb") << qreal(0.0) << 7; +} + +void tst_QColor::qcolorprofile() +{ + QFETCH(qreal, gammaC); + QFETCH(int, tolerance); + QColorProfile *cp = (gammaC == 0) ? QColorProfile::fromSRgb(): QColorProfile::fromGamma(gammaC); + + // Test we are accurate for most values after converting through gamma-correction. + int error = 0; + for (uint i = 0; i < 256; i++) { + QRgb cin = qRgb(i, i, i); + QRgba64 tmp = cp->toLinear64(cin); + QRgb cout = cp->fromLinear64(tmp); + error += qAbs(qRed(cin) - qRed(cout)); + } + QVERIFY(error <= tolerance); + delete cp; +} + QTEST_MAIN(tst_QColor) #include "tst_qcolor.moc" diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index cf4979e291..3562bc63f4 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -4843,6 +4843,18 @@ void tst_QPainter::blendARGBonRGB_data() << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 127; QTest::newRow("ARGB_PM source-in RGBx8888") << QImage::Format_RGBX8888 << QImage::Format_ARGB32_Premultiplied << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 127; + QTest::newRow("ARGB over RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32 + << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 127; + QTest::newRow("ARGB_PM over RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32_Premultiplied + << QPainter::CompositionMode_SourceOver << qRgba(127, 0, 0, 127) << 127; + QTest::newRow("ARGB source RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32 + << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 255; + QTest::newRow("ARGB_PM source RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32_Premultiplied + << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 255; + QTest::newRow("ARGB source-in RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32 + << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 255; + QTest::newRow("ARGB_PM source-in RGBA8888") << QImage::Format_RGBA8888 << QImage::Format_ARGB32_Premultiplied + << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 255; QTest::newRow("ARGB over RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32 << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 123; QTest::newRow("ARGB_PM over RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32_Premultiplied @@ -4905,7 +4917,7 @@ void tst_QPainter::blendARGBonRGB() painter.drawImage(0, 0, imageArgb); painter.end(); - QCOMPARE(qRed(imageRgb.pixel(0,0)), expected_red); + QCOMPARE(imageRgb.pixelColor(0,0).red(), expected_red); } enum CosmeticStrokerPaint diff --git a/tests/auto/gui/qopengl/qopengl.pro b/tests/auto/gui/qopengl/qopengl.pro index aaef6e5125..d744d37280 100644 --- a/tests/auto/gui/qopengl/qopengl.pro +++ b/tests/auto/gui/qopengl/qopengl.pro @@ -8,4 +8,4 @@ QT += gui-private core-private testlib SOURCES += tst_qopengl.cpp -linux:qtConfig(xcb-glx):qtConfig(xcb-xlib):!qtConfig(egl): DEFINES += USE_GLX +linux:qtConfig(xcb):qtConfig(xcb-glx):qtConfig(xcb-xlib):!qtConfig(egl): DEFINES += USE_GLX diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp index 4cdd8202e9..6d9456fa69 100644 --- a/tests/auto/gui/qopengl/tst_qopengl.cpp +++ b/tests/auto/gui/qopengl/tst_qopengl.cpp @@ -67,6 +67,7 @@ class tst_QOpenGL : public QObject Q_OBJECT private slots: + void initTestCase(); void sharedResourceCleanup_data(); void sharedResourceCleanup(); void multiGroupSharedResourceCleanup_data(); @@ -86,6 +87,7 @@ private slots: void fboMRT_differentFormats(); void openGLPaintDevice_data(); void openGLPaintDevice(); + void openGLPaintDeviceWithChangingContext(); void aboutToBeDestroyed(); void sizeLessWindow(); void QTBUG15621_triangulatingStrokerDivZero(); @@ -204,6 +206,12 @@ static QSurface *createSurface(int surfaceClass) return 0; } +void tst_QOpenGL::initTestCase() +{ + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) + QSKIP("OpenGL is not supported on this platform."); +} + static void common_data() { QTest::addColumn<int>("surfaceClass"); @@ -949,6 +957,14 @@ void tst_QOpenGL::openGLPaintDevice_data() QTest::newRow("Using QOffscreenSurface - RGB16") << int(QSurface::Offscreen) << QImage::Format_RGB16; } +static void drawColoredRects(QPainter *p, const QSize &size) +{ + p->fillRect(0, 0, size.width() / 2, size.height() / 2, Qt::red); + p->fillRect(size.width() / 2, 0, size.width() / 2, size.height() / 2, Qt::green); + p->fillRect(size.width() / 2, size.height() / 2, size.width() / 2, size.height() / 2, Qt::blue); + p->fillRect(0, size.height() / 2, size.width() / 2, size.height() / 2, Qt::white); +} + void tst_QOpenGL::openGLPaintDevice() { #if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(__x86_64__) @@ -971,10 +987,7 @@ void tst_QOpenGL::openGLPaintDevice() QImage image(size, imageFormat); QPainter p(&image); - p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red); - p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green); - p.fillRect(image.width() / 2, image.height() / 2, image.width() / 2, image.height() / 2, Qt::blue); - p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white); + drawColoredRects(&p, image.size()); p.end(); QOpenGLFramebufferObject fbo(size); @@ -982,10 +995,7 @@ void tst_QOpenGL::openGLPaintDevice() QOpenGLPaintDevice device(size); QVERIFY(p.begin(&device)); - p.fillRect(0, 0, image.width() / 2, image.height() / 2, Qt::red); - p.fillRect(image.width() / 2, 0, image.width() / 2, image.height() / 2, Qt::green); - p.fillRect(image.width() / 2, image.height() / 2, image.width() / 2, image.height() / 2, Qt::blue); - p.fillRect(0, image.height() / 2, image.width() / 2, image.height() / 2, Qt::white); + drawColoredRects(&p, image.size()); p.end(); QImage actual = fbo.toImage().convertToFormat(imageFormat); @@ -1011,6 +1021,59 @@ void tst_QOpenGL::openGLPaintDevice() QCOMPARE(image, actual); } +void tst_QOpenGL::openGLPaintDeviceWithChangingContext() +{ + QScopedPointer<QSurface> surface(createSurface(QSurface::Window)); + const QSize size(512, 512); + + // QOpenGLPaintDevice has a thread-local paint engine. Therefore render + // twice, with a different context and device. Under the hood it will + // still use the same paint engine! + + QOpenGLContext ctx; + QVERIFY(ctx.create()); + QVERIFY(ctx.makeCurrent(surface.data())); + + QOpenGLFramebufferObject fbo(size); + QVERIFY(fbo.bind()); + + QOpenGLPaintDevice device(size); + + QPainter p; + QVERIFY(p.begin(&device)); + drawColoredRects(&p, size); + p.end(); + + QImage img1 = fbo.toImage(); + + QOpenGLContext ctx2; + // When supported, test the special case, where the second context is + // totally incompatible due to being a core profile one. + QSurfaceFormat coreFormat; + coreFormat.setVersion(3, 2); + coreFormat.setProfile(QSurfaceFormat::CoreProfile); + ctx2.setFormat(coreFormat); + if (!ctx2.create() || !ctx2.makeCurrent(surface.data())) { + ctx2.setFormat(QSurfaceFormat()); + QVERIFY(ctx2.create()); + } + + QVERIFY(ctx2.makeCurrent(surface.data())); + + QOpenGLFramebufferObject fbo2(size); + QVERIFY(fbo2.bind()); + + QOpenGLPaintDevice device2(size); + + QVERIFY(p.begin(&device2)); + drawColoredRects(&p, size); + p.end(); + + QImage img2 = fbo2.toImage(); + + QFUZZY_COMPARE_IMAGES(img1, img2); +} + void tst_QOpenGL::aboutToBeDestroyed() { QWindow window; diff --git a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp index 39f7beca6f..f8dfdbd3b0 100644 --- a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp +++ b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp @@ -100,6 +100,7 @@ class tst_QOpenGlConfig : public QObject Q_OBJECT private slots: + void initTestCase(); void testConfiguration(); void testGlConfiguration(); void testBugList(); @@ -162,6 +163,12 @@ static void dumpConfiguration(QTextStream &str) } } +void tst_QOpenGlConfig::initTestCase() +{ + if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) + QSKIP("OpenGL is not supported on this platform."); +} + void tst_QOpenGlConfig::testConfiguration() { QString result; diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp index e8244a0e5d..e52cb63384 100644 --- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp +++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp @@ -244,8 +244,13 @@ void tst_QFontDatabase::addAppFont() QVERIFY(!newFamilies.isEmpty()); QVERIFY(newFamilies.count() >= oldFamilies.count()); - for (int i = 0; i < addedFamilies.count(); ++i) - QVERIFY(newFamilies.contains(addedFamilies.at(i))); + for (int i = 0; i < addedFamilies.count(); ++i) { + QString family = addedFamilies.at(i); + QVERIFY(newFamilies.contains(family)); + QFont qfont(family); + QFontInfo fi(qfont); + QCOMPARE(fi.family(), family); + } QVERIFY(QFontDatabase::removeApplicationFont(id)); QCOMPARE(fontDbChangedSpy.count(), 2); diff --git a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp index 6192e3cd8d..8667caa1ef 100644 --- a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp @@ -202,36 +202,36 @@ void tst_QFontMetrics::bypassShaping() QCOMPARE(textWidth, charsWidth); } -template<class FontMetrics> void elidedMultiLength_helper() +template<class FontMetrics, typename PrimitiveType> void elidedMultiLength_helper() { QString text1 = QLatin1String("Long Text 1\x9cShorter\x9csmall"); QString text1_long = "Long Text 1"; QString text1_short = "Shorter"; QString text1_small = "small"; FontMetrics fm = FontMetrics(QFont()); - int width_long = fm.size(0, text1_long).width(); + PrimitiveType width_long = fm.size(0, text1_long).width(); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, 8000), text1_long); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long + 1), text1_long); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long - 1), text1_short); - int width_short = fm.size(0, text1_short).width(); + PrimitiveType width_short = fm.size(0, text1_short).width(); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short + 1), text1_short); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short - 1), text1_small); // Not even wide enough for "small" - should use ellipsis QChar ellipsisChar(0x2026); QString text1_el = QString::fromLatin1("s") + ellipsisChar; - int width_small = fm.width(text1_el); + PrimitiveType width_small = fm.width(text1_el); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_small + 1), text1_el); } void tst_QFontMetrics::elidedMultiLength() { - elidedMultiLength_helper<QFontMetrics>(); + elidedMultiLength_helper<QFontMetrics, int>(); } void tst_QFontMetrics::elidedMultiLengthF() { - elidedMultiLength_helper<QFontMetricsF>(); + elidedMultiLength_helper<QFontMetricsF, qreal>(); } void tst_QFontMetrics::inFontUcs4() diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp index 7c60c8c9f8..21b2697b90 100644 --- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp +++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp @@ -527,6 +527,7 @@ void tst_QGlyphRun::drawStruckOutText() QFont font; font.setStrikeOut(true); + font.setStyleStrategy(QFont::ForceIntegerMetrics); QTextLayout layout(s); layout.setFont(font); @@ -569,6 +570,7 @@ void tst_QGlyphRun::drawOverlinedText() QFont font; font.setOverline(true); + font.setStyleStrategy(QFont::ForceIntegerMetrics); QTextLayout layout(s); layout.setFont(font); @@ -611,6 +613,7 @@ void tst_QGlyphRun::drawUnderlinedText() QFont font; font.setUnderline(true); + font.setStyleStrategy(QFont::ForceIntegerMetrics); QTextLayout layout(s); layout.setFont(font); diff --git a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp b/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp index 9f84f64ee9..f4e3356ad0 100644 --- a/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/gui/text/qstatictext/tst_qstatictext.cpp @@ -716,6 +716,7 @@ void tst_QStaticText::drawStruckOutText() QFont font; font.setStrikeOut(true); + font.setStyleStrategy(QFont::ForceIntegerMetrics); { QPainter p(&imageDrawText); @@ -751,6 +752,7 @@ void tst_QStaticText::drawOverlinedText() QFont font; font.setOverline(true); + font.setStyleStrategy(QFont::ForceIntegerMetrics); { QPainter p(&imageDrawText); @@ -786,6 +788,7 @@ void tst_QStaticText::drawUnderlinedText() QFont font; font.setUnderline(true); + font.setStyleStrategy(QFont::ForceIntegerMetrics); { QPainter p(&imageDrawText); diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index de5b2a8676..764b99646b 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -134,7 +134,9 @@ private slots: void clearResources(); void setPlainText(); + void toPlainText_data(); void toPlainText(); + void toRawText(); void deleteTextObjectsOnClear(); @@ -2390,12 +2392,39 @@ void tst_QTextDocument::setPlainText() QCOMPARE(doc->toPlainText(), s); } +void tst_QTextDocument::toPlainText_data() +{ + QTest::addColumn<QString>("html"); + QTest::addColumn<QString>("expectedPlainText"); + + QTest::newRow("nbsp") << "Hello World" << "Hello World"; + QTest::newRow("empty_div") << "<div></div>hello" << "hello"; + QTest::newRow("br_and_p") << "<p>first<br></p><p>second<br></p>" << "first\n\nsecond\n"; + QTest::newRow("div") << "first<div>second<br>third</div>fourth" << "first\nsecond\nthird\nfourth"; // <div> and </div> become newlines... + QTest::newRow("br_text_end_of_div") << "<div><div>first<br>moretext</div>second<br></div>" << "first\nmoretext\nsecond\n"; // ... when there is text before <div> + QTest::newRow("br_end_of_div_like_gmail") << "<div><div><div>first<br></div>second<br></div>third<br></div>" << "first\nsecond\nthird\n"; // ... and when there is text before </div> + QTest::newRow("p_and_div") << "<div><div>first<p>second</p></div>third</div>" << "first\nsecond\nthird"; +} + void tst_QTextDocument::toPlainText() { - doc->setHtml("Hello World"); - QCOMPARE(doc->toPlainText(), QLatin1String("Hello World")); + QFETCH(QString, html); + QFETCH(QString, expectedPlainText); + + doc->setHtml(html); + QCOMPARE(doc->toPlainText(), expectedPlainText); } +void tst_QTextDocument::toRawText() +{ + doc->setHtml(" "); + + QString rawText = doc->toRawText(); + QCOMPARE(rawText.size(), 1); + QCOMPARE(rawText.at(0).unicode(), ushort(QChar::Nbsp)); +} + + void tst_QTextDocument::deleteTextObjectsOnClear() { QPointer<QTextTable> table = cursor.insertTable(2, 2); diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index 36907b9258..ee50b98733 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -1104,7 +1104,7 @@ void tst_QTextScriptEngine::controlInSyllable_qtbug14204() const ushort *log_clusters = e->logClusters(&e->layoutData->items[0]); QCOMPARE(log_clusters[0], ushort(0)); QCOMPARE(log_clusters[1], ushort(0)); - QCOMPARE(log_clusters[2], ushort(1)); + QCOMPARE(log_clusters[2], ushort(0)); QCOMPARE(log_clusters[3], ushort(2)); } @@ -1214,6 +1214,9 @@ void tst_QTextScriptEngine::thaiWithZWJ() QFont font(QStringLiteral("Waree")); font.setStyleStrategy(QFont::NoFontMerging); + if (QFontInfo(font).styleName() != QStringLiteral("Book")) + QSKIP("couldn't find 'Waree Book' font"); + QString s(QString::fromUtf8("\xe0\xb8\xa3\xe2\x80\x8d\xe0\xb8\xa3\xe2\x80" "\x8c\x2e\xe0\xb8\xa3\x2e\xe2\x80\x9c\xe0\xb8" "\xa3\xe2\x80\xa6\xe0\xb8\xa3\xe2\x80\x9d\xe0" @@ -1233,20 +1236,22 @@ void tst_QTextScriptEngine::thaiWithZWJ() QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(2)); // Thai: Thai character followed by superscript "a" which is of inherited type //A quick sanity check - check all the characters are individual clusters + // A thai implementation could either remove the ZWJ and ZWNJ characters, or hide them. + // The current implementation hides them, so we test for that. unsigned short *logClusters = e->layoutData->logClustersPtr; - for (int i = 0; i < 15; i++) + QCOMPARE(logClusters[0], ushort(0)); + QCOMPARE(logClusters[1], ushort(0)); + QCOMPARE(logClusters[2], ushort(2)); + QCOMPARE(logClusters[3], ushort(2)); + for (int i = 4; i < 15; i++) QCOMPARE(logClusters[i], ushort(i)); for (int i = 0; i < 3; i++) QCOMPARE(logClusters[i+15], ushort(0)); - // A thai implementation could either remove the ZWJ and ZWNJ characters, or hide them. - // The current implementation hides them, so we test for that. // The only characters that we should be hiding are the ZWJ and ZWNJ characters in position 1 and 3. const QGlyphLayout glyphLayout = e->layoutData->glyphLayout; for (int i = 0; i < 18; i++) { - if (i == 17) - QCOMPARE(glyphLayout.advances[i].toInt(), 0); - else if (i == 1 || i == 3) + if (i == 1 || i == 3) QCOMPARE(glyphLayout.advances[i].toInt(), 0); else QVERIFY(glyphLayout.advances[i].toInt() != 0); |