diff options
Diffstat (limited to 'tests/auto/gui')
-rw-r--r-- | tests/auto/gui/gui.pro | 3 | ||||
-rw-r--r-- | tests/auto/gui/image/qicon/tst_qicon.cpp | 10 | ||||
-rw-r--r-- | tests/auto/gui/image/qimage/tst_qimage.cpp | 85 | ||||
-rw-r--r-- | tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp | 16 | ||||
-rw-r--r-- | tests/auto/gui/kernel/kernel.pro | 1 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qcursor/qcursor.pro | 6 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qcursor/tst_qcursor.cpp | 123 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp | 12 | ||||
-rw-r--r-- | tests/auto/gui/painting/qcolor/tst_qcolor.cpp | 27 | ||||
-rw-r--r-- | tests/auto/gui/painting/qpainter/tst_qpainter.cpp | 53 | ||||
-rw-r--r-- | tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp | 42 | ||||
-rw-r--r-- | tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp | 103 | ||||
-rw-r--r-- | tests/auto/gui/qvulkan/qvulkan.pro | 9 | ||||
-rw-r--r-- | tests/auto/gui/qvulkan/tst_qvulkan.cpp | 435 | ||||
-rw-r--r-- | tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp | 49 |
15 files changed, 793 insertions, 181 deletions
diff --git a/tests/auto/gui/gui.pro b/tests/auto/gui/gui.pro index 2fd3024afe..d7cda11513 100644 --- a/tests/auto/gui/gui.pro +++ b/tests/auto/gui/gui.pro @@ -9,8 +9,11 @@ SUBDIRS = \ painting \ qopenglconfig \ qopengl \ + qvulkan \ text \ util \ itemmodels \ !qtConfig(opengl): SUBDIRS -= qopengl qopenglconfig + +!qtConfig(vulkan): SUBDIRS -= qvulkan diff --git a/tests/auto/gui/image/qicon/tst_qicon.cpp b/tests/auto/gui/image/qicon/tst_qicon.cpp index e031ffec71..571a3c6984 100644 --- a/tests/auto/gui/image/qicon/tst_qicon.cpp +++ b/tests/auto/gui/image/qicon/tst_qicon.cpp @@ -530,16 +530,6 @@ void tst_QIcon::streamAvailableSizes() } } - -static inline bool operator<(const QSize &lhs, const QSize &rhs) -{ - if (lhs.width() < rhs.width()) - return true; - else if (lhs.width() == lhs.width()) - return lhs.height() < lhs.height(); - return false; -} - #ifndef QT_NO_WIDGETS void tst_QIcon::task184901_badCache() { diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index fac785ac86..af769403bf 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -222,65 +222,65 @@ private: const QString m_prefix; }; -static QString formatToString(QImage::Format format) +static QLatin1String formatToString(QImage::Format format) { switch (format) { case QImage::Format_Invalid: - return QStringLiteral("Invalid"); + return QLatin1String("Invalid"); case QImage::Format_Mono: - return QStringLiteral("Mono"); + return QLatin1String("Mono"); case QImage::Format_MonoLSB: - return QStringLiteral("MonoLSB"); + return QLatin1String("MonoLSB"); case QImage::Format_Indexed8: - return QStringLiteral("Indexed8"); + return QLatin1String("Indexed8"); case QImage::Format_RGB32: - return QStringLiteral("RGB32"); + return QLatin1String("RGB32"); case QImage::Format_ARGB32: - return QStringLiteral("ARGB32"); + return QLatin1String("ARGB32"); case QImage::Format_ARGB32_Premultiplied: - return QStringLiteral("ARGB32pm"); + return QLatin1String("ARGB32pm"); case QImage::Format_RGB16: - return QStringLiteral("RGB16"); + return QLatin1String("RGB16"); case QImage::Format_ARGB8565_Premultiplied: - return QStringLiteral("ARGB8565pm"); + return QLatin1String("ARGB8565pm"); case QImage::Format_RGB666: - return QStringLiteral("RGB666"); + return QLatin1String("RGB666"); case QImage::Format_ARGB6666_Premultiplied: - return QStringLiteral("ARGB6666pm"); + return QLatin1String("ARGB6666pm"); case QImage::Format_RGB555: - return QStringLiteral("RGB555"); + return QLatin1String("RGB555"); case QImage::Format_ARGB8555_Premultiplied: - return QStringLiteral("ARGB8555pm"); + return QLatin1String("ARGB8555pm"); case QImage::Format_RGB888: - return QStringLiteral("RGB888"); + return QLatin1String("RGB888"); case QImage::Format_RGB444: - return QStringLiteral("RGB444"); + return QLatin1String("RGB444"); case QImage::Format_ARGB4444_Premultiplied: - return QStringLiteral("ARGB4444pm"); + return QLatin1String("ARGB4444pm"); case QImage::Format_RGBX8888: - return QStringLiteral("RGBx88888"); + return QLatin1String("RGBx88888"); case QImage::Format_RGBA8888: - return QStringLiteral("RGBA88888"); + return QLatin1String("RGBA88888"); case QImage::Format_RGBA8888_Premultiplied: - return QStringLiteral("RGBA88888pm"); + return QLatin1String("RGBA88888pm"); case QImage::Format_BGR30: - return QStringLiteral("BGR30"); + return QLatin1String("BGR30"); case QImage::Format_A2BGR30_Premultiplied: - return QStringLiteral("A2BGR30pm"); + return QLatin1String("A2BGR30pm"); case QImage::Format_RGB30: - return QStringLiteral("RGB30"); + return QLatin1String("RGB30"); case QImage::Format_A2RGB30_Premultiplied: - return QStringLiteral("A2RGB30pm"); + return QLatin1String("A2RGB30pm"); case QImage::Format_Alpha8: - return QStringLiteral("Alpha8"); + return QLatin1String("Alpha8"); case QImage::Format_Grayscale8: - return QStringLiteral("Grayscale8"); + return QLatin1String("Grayscale8"); default: break; }; Q_UNREACHABLE(); qWarning("Unhandled image format"); - return QStringLiteral("unknown"); + return QLatin1String("unknown"); } tst_QImage::tst_QImage() @@ -2321,7 +2321,7 @@ void tst_QImage::rgbSwapped_data() QTest::addColumn<QImage::Format>("format"); for (int i = QImage::Format_Indexed8; i < QImage::Format_Alpha8; ++i) { - QTest::newRow(qPrintable(formatToString(QImage::Format(i)))) << QImage::Format(i); + QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i); } } @@ -2576,11 +2576,12 @@ void tst_QImage::inplaceMirrored_data() continue; if (i == QImage::Format_RGB444 || i == QImage::Format_ARGB4444_Premultiplied) continue; - QTest::newRow(qPrintable(formatToString(QImage::Format(i)) + QStringLiteral(", vertical"))) + const auto fmt = formatToString(QImage::Format(i)); + QTest::addRow("%s, vertical", fmt.data()) << QImage::Format(i) << true << false; - QTest::newRow(qPrintable(formatToString(QImage::Format(i)) + QStringLiteral(", horizontal"))) + QTest::addRow("%s, horizontal", fmt.data()) << QImage::Format(i) << false << true; - QTest::newRow(qPrintable(formatToString(QImage::Format(i)) + QStringLiteral(", horizontal+vertical"))) + QTest::addRow("%s, horizontal+vertical", fmt.data()) << QImage::Format(i) << true << true; } } @@ -2744,12 +2745,12 @@ void tst_QImage::genericRgbConversion_data() QTest::addColumn<QImage::Format>("dest_format"); for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) { - const QString formatI = formatToString(QImage::Format(i)); + const QLatin1String formatI = formatToString(QImage::Format(i)); for (int j = QImage::Format_RGB32; j < QImage::Format_Alpha8; ++j) { if (i == j) continue; - const QString test = formatI + QLatin1String(" -> ") + formatToString(QImage::Format(j)); - QTest::newRow(qPrintable(test)) << QImage::Format(i) << QImage::Format(j); + QTest::addRow("%s -> %s", formatI.data(), formatToString(QImage::Format(j)).data()) + << QImage::Format(i) << QImage::Format(j); } } } @@ -2786,8 +2787,8 @@ void tst_QImage::inplaceRgbConversion_data() 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); + QTest::addRow("%s -> %s", formatToString(QImage::Format(i)).data(), formatToString(QImage::Format(j)).data()) + << QImage::Format(i) << QImage::Format(j); } } } @@ -2953,7 +2954,7 @@ void tst_QImage::invertPixelsRGB_data() QTest::addColumn<QImage::Format>("image_format"); for (int i = QImage::Format_RGB32; i < QImage::Format_Alpha8; ++i) { - QTest::newRow(qPrintable(formatToString(QImage::Format(i)))) << QImage::Format(i); + QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i); } } @@ -3130,10 +3131,10 @@ void tst_QImage::rgb30Repremul_data() { QTest::addColumn<uint>("color"); for (int i = 255; i > 0; i -= 15) { - QTest::newRow(qPrintable(QStringLiteral("100% red=") + QString::number(i))) << qRgba(i, 0, 0, 0xff); - QTest::newRow(qPrintable(QStringLiteral("75% red=") + QString::number(i))) << qRgba(i, 0, 0, 0xc0); - QTest::newRow(qPrintable(QStringLiteral("50% red=") + QString::number(i))) << qRgba(i, 0, 0, 0x80); - QTest::newRow(qPrintable(QStringLiteral("37.5% red=") + QString::number(i))) << qRgba(i, 0, 0, 0x60); + QTest::addRow("100%% red=%d", i) << qRgba(i, 0, 0, 0xff); + QTest::addRow("75%% red=%d", i) << qRgba(i, 0, 0, 0xc0); + QTest::addRow("50%% red=%d", i) << qRgba(i, 0, 0, 0x80); + QTest::addRow("37.5%% red=%d", i) << qRgba(i, 0, 0, 0x60); } } @@ -3393,7 +3394,7 @@ void tst_QImage::toCGImage_data() QImage::Format_RGBA8888, QImage::Format_RGBX8888, QImage::Format_ARGB32_Premultiplied }; for (int i = QImage::Format_Invalid; i < QImage::Format_Grayscale8; ++i) { - QTest::newRow(qPrintable(formatToString(QImage::Format(i)))) + QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i) << supported.contains(QImage::Format(i)); } } diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index d5c624833c..2381fd9246 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -77,6 +77,9 @@ private slots: void saveWithNoFormat(); void saveToTemporaryFile(); + + void writeEmpty(); + private: QTemporaryDir m_temporaryDir; QString prefix; @@ -529,5 +532,18 @@ void tst_QImageWriter::saveToTemporaryFile() } } +void tst_QImageWriter::writeEmpty() +{ + // check writing a null QImage errors gracefully + QTemporaryDir dir; + QVERIFY2(dir.isValid(), qPrintable(dir.errorString())); + QString fileName(dir.path() + QLatin1String("/testimage.bmp")); + QVERIFY(!QFileInfo(fileName).exists()); + QImageWriter writer(fileName); + QVERIFY(!writer.write(QImage())); + QCOMPARE(writer.error(), QImageWriter::InvalidImageError); + QVERIFY(!QFileInfo(fileName).exists()); +} + QTEST_MAIN(tst_QImageWriter) #include "tst_qimagewriter.moc" diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index 559395a9ae..46786262c0 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -2,6 +2,7 @@ TEMPLATE=subdirs SUBDIRS=\ qbackingstore \ qclipboard \ + qcursor \ qdrag \ qevent \ qfileopenevent \ diff --git a/tests/auto/gui/kernel/qcursor/qcursor.pro b/tests/auto/gui/kernel/qcursor/qcursor.pro new file mode 100644 index 0000000000..16e7d7c41c --- /dev/null +++ b/tests/auto/gui/kernel/qcursor/qcursor.pro @@ -0,0 +1,6 @@ +QT += testlib +TARGET = tst_qcursor +CONFIG += testcase +CONFIG -= app_bundle + +SOURCES += tst_qcursor.cpp diff --git a/tests/auto/gui/kernel/qcursor/tst_qcursor.cpp b/tests/auto/gui/kernel/qcursor/tst_qcursor.cpp new file mode 100644 index 0000000000..d505f5a655 --- /dev/null +++ b/tests/auto/gui/kernel/qcursor/tst_qcursor.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** 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/QTest> +#include <qcursor.h> +#include <qpixmap.h> +#include <qbitmap.h> + +class tst_QCursor : public QObject +{ + Q_OBJECT + +private slots: + void equality(); +}; + +#define VERIFY_EQUAL(lhs, rhs) \ + QVERIFY(lhs == rhs); \ + QVERIFY(rhs == lhs); \ + QVERIFY(!(rhs != lhs)); \ + QVERIFY(!(lhs != rhs)) + +#define VERIFY_DIFFERENT(lhs, rhs) \ + QVERIFY(lhs != rhs); \ + QVERIFY(rhs != lhs); \ + QVERIFY(!(rhs == lhs)); \ + QVERIFY(!(lhs == rhs)) + +void tst_QCursor::equality() +{ + VERIFY_EQUAL(QCursor(), QCursor()); + VERIFY_EQUAL(QCursor(Qt::CrossCursor), QCursor(Qt::CrossCursor)); + VERIFY_DIFFERENT(QCursor(Qt::CrossCursor), QCursor()); + + // Shape + QCursor shapeCursor(Qt::WaitCursor); + VERIFY_EQUAL(shapeCursor, shapeCursor); + QCursor shapeCursorCopy(shapeCursor); + VERIFY_EQUAL(shapeCursor, shapeCursorCopy); + shapeCursorCopy.setShape(Qt::DragMoveCursor); + VERIFY_DIFFERENT(shapeCursor, shapeCursorCopy); + shapeCursorCopy.setShape(shapeCursor.shape()); + VERIFY_EQUAL(shapeCursor, shapeCursorCopy); + + // Pixmap + QPixmap pixmap(16, 16); + QCursor pixmapCursor(pixmap); + VERIFY_EQUAL(pixmapCursor, pixmapCursor); + VERIFY_EQUAL(pixmapCursor, QCursor(pixmapCursor)); + VERIFY_EQUAL(pixmapCursor, QCursor(pixmap)); + VERIFY_DIFFERENT(pixmapCursor, QCursor()); + VERIFY_DIFFERENT(pixmapCursor, QCursor(pixmap, 5, 5)); + VERIFY_DIFFERENT(pixmapCursor, QCursor(QPixmap(16, 16))); + VERIFY_DIFFERENT(pixmapCursor, shapeCursor); + + // Bitmap & mask + QBitmap bitmap(16, 16); + QBitmap mask(16, 16); + QCursor bitmapCursor(bitmap, mask); + VERIFY_EQUAL(bitmapCursor, bitmapCursor); + VERIFY_EQUAL(bitmapCursor, QCursor(bitmapCursor)); + VERIFY_EQUAL(bitmapCursor, QCursor(bitmap, mask)); + VERIFY_DIFFERENT(bitmapCursor, QCursor()); + VERIFY_DIFFERENT(bitmapCursor, QCursor(bitmap, mask, 5, 5)); + VERIFY_DIFFERENT(bitmapCursor, QCursor(bitmap, QBitmap(16, 16))); + VERIFY_DIFFERENT(bitmapCursor, QCursor(QBitmap(16, 16), mask)); + VERIFY_DIFFERENT(bitmapCursor, shapeCursor); + VERIFY_DIFFERENT(bitmapCursor, pixmapCursor); + + // Empty pixmap + QPixmap emptyPixmap; + QCursor emptyPixmapCursor(emptyPixmap); + QCOMPARE(emptyPixmapCursor.shape(), Qt::ArrowCursor); + VERIFY_EQUAL(emptyPixmapCursor, QCursor()); + VERIFY_EQUAL(emptyPixmapCursor, QCursor(emptyPixmap, 5, 5)); + VERIFY_DIFFERENT(emptyPixmapCursor, shapeCursor); + VERIFY_DIFFERENT(emptyPixmapCursor, pixmapCursor); + VERIFY_DIFFERENT(emptyPixmapCursor, bitmapCursor); + + // Empty bitmap & mask + QBitmap emptyBitmap; + QCursor emptyBitmapCursor(emptyBitmap, emptyBitmap); + QCOMPARE(emptyBitmapCursor.shape(), Qt::ArrowCursor); + VERIFY_EQUAL(emptyBitmapCursor, QCursor()); + VERIFY_EQUAL(emptyBitmapCursor, QCursor(emptyBitmap, emptyBitmap, 5, 5)); + VERIFY_EQUAL(emptyBitmapCursor, QCursor(emptyBitmap, mask)); + VERIFY_EQUAL(emptyBitmapCursor, QCursor(bitmap, emptyBitmap)); + VERIFY_EQUAL(emptyBitmapCursor, emptyPixmapCursor); + VERIFY_DIFFERENT(emptyBitmapCursor, shapeCursor); + VERIFY_DIFFERENT(emptyBitmapCursor, pixmapCursor); + VERIFY_DIFFERENT(emptyBitmapCursor, bitmapCursor); +} + +#undef VERIFY_EQUAL +#undef VERIFY_DIFFERENT + +QTEST_MAIN(tst_QCursor) +#include "tst_qcursor.moc" diff --git a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp index 6394a956bd..f8b6bf064a 100644 --- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp @@ -36,14 +36,18 @@ #include <QLibraryInfo> #ifdef Q_OS_MAC -#ifdef Q_OS_OSX -#include <Carbon/Carbon.h> -#endif struct MacSpecialKey { int key; ushort macSymbol; }; +// Unicode code points for the glyphs associated with these keys +// Defined by Carbon headers but not anywhere in Cocoa +static const int kShiftUnicode = 0x21E7; +static const int kControlUnicode = 0x2303; +static const int kOptionUnicode = 0x2325; +static const int kCommandUnicode = 0x2318; + static const int NumEntries = 21; static const MacSpecialKey entries[NumEntries] = { { Qt::Key_Escape, 0x238B }, @@ -61,12 +65,10 @@ static const MacSpecialKey entries[NumEntries] = { { Qt::Key_Down, 0x2193 }, { Qt::Key_PageUp, 0x21DE }, { Qt::Key_PageDown, 0x21DF }, -#ifdef Q_OS_OSX { Qt::Key_Shift, kShiftUnicode }, { Qt::Key_Control, kCommandUnicode }, { Qt::Key_Meta, kControlUnicode }, { Qt::Key_Alt, kOptionUnicode }, -#endif { Qt::Key_CapsLock, 0x21EA }, }; diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index 1ce7e797fc..6809aea086 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -545,19 +545,32 @@ void tst_QColor::setNamedColor_data() QColor bySetNamedColor; \ bySetNamedColor.setNamedColor(expr); \ auto byCtor = QColor(expr); \ - QTest::newRow(e.name + QByteArrayLiteral(#expr)) \ + QTest::addRow("%s: %s", e.name, #expr) \ << byCtor << bySetNamedColor << expected; \ } while (0) \ /*end*/ - ROW(QLatin1String(e.name)); - ROW(QString(QLatin1String(e.name))); + const auto l1 = QLatin1String(e.name); + const auto l1UpperBA = QByteArray(e.name).toUpper(); + const auto l1Upper = QLatin1String(l1UpperBA); + const auto l1SpaceBA = QByteArray(e.name).insert(1, ' '); + const auto l1Space = QLatin1String(l1SpaceBA); + + const auto u16 = QString(l1); + const auto u16Upper = u16.toUpper(); + const auto u16Space = QString(u16).insert(1, ' '); + + ROW(l1); + ROW(u16); + ROW(QStringView(u16)); // name should be case insensitive - ROW(QLatin1String(QByteArray(e.name).toUpper())); - ROW(QString(e.name).toUpper()); + ROW(l1Upper); + ROW(u16Upper); + ROW(QStringView(u16Upper)); // spaces should be ignored - ROW(QLatin1String(QByteArray(e.name).insert(1, ' '))); - ROW(QString(e.name).insert(1, ' ')); + ROW(l1Space); + ROW(u16Space); + ROW(QStringView(u16Space)); #undef ROW } } diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 8db4489ec1..ed5b9fabb6 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -397,51 +397,6 @@ void tst_QPainter::cleanupTestCase() QFile::remove(QLatin1String("foo.png")); } -static const char* const maskSource_data[] = { -"16 13 6 1", -". c None", -"d c #000000", -"# c #999999", -"c c #cccccc", -"b c #ffff00", -"a c #ffffff", -"...#####........", -"..#aaaaa#.......", -".#abcbcba######.", -".#acbcbcaaaaaa#d", -".#abcbcbcbcbcb#d", -"#############b#d", -"#aaaaaaaaaa##c#d", -"#abcbcbcbcbbd##d", -".#abcbcbcbcbcd#d", -".#acbcbcbcbcbd#d", -"..#acbcbcbcbb#dd", -"..#############d", -"...ddddddddddddd"}; - -static const char* const maskResult_data[] = { -"16 13 6 1", -". c #ff0000", -"d c #000000", -"# c #999999", -"c c #cccccc", -"b c #ffff00", -"a c #ffffff", -"...#####........", -"..#aaaaa#.......", -".#abcbcba######.", -".#acbcbcaaaaaa#d", -".#abcbcbcbcbcb#d", -"#############b#d", -"#aaaaaaaaaa##c#d", -"#abcbcbcbcbbd##d", -".#abcbcbcbcbcd#d", -".#acbcbcbcbcbd#d", -"..#acbcbcbcbb#dd", -"..#############d", -"...ddddddddddddd"}; - - #ifndef QT_NO_WIDGETS void tst_QPainter::drawPixmap_comp_data() { @@ -3557,11 +3512,9 @@ void tst_QPainter::drawImage_data() continue; for (int odd_x = 0; odd_x <= 1; ++odd_x) { for (int odd_width = 0; odd_width <= 1; ++odd_width) { - QString description = - QString("srcFormat %1, dstFormat %2, odd x: %3, odd width: %4") - .arg(srcFormat).arg(dstFormat).arg(odd_x).arg(odd_width); - - QTest::newRow(qPrintable(description)) << (10 + odd_x) << 10 << (20 + odd_width) << 20 + QTest::addRow("srcFormat %d, dstFormat %d, odd x: %d, odd width: %d", + srcFormat, dstFormat, odd_x, odd_width) + << (10 + odd_x) << 10 << (20 + odd_width) << 20 << QImage::Format(srcFormat) << QImage::Format(dstFormat); } diff --git a/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp b/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp index 13b6e28f5f..bf3e5dfb52 100644 --- a/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp +++ b/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp @@ -49,6 +49,8 @@ private slots: void boundingRectF(); void makeEllipse(); void swap(); + void intersections_data(); + void intersections(); }; tst_QPolygon::tst_QPolygon() @@ -159,5 +161,45 @@ void tst_QPolygon::swap() QCOMPARE(p2.count(),3); } +void tst_QPolygon::intersections_data() +{ + QTest::addColumn<QPolygon>("poly1"); + QTest::addColumn<QPolygon>("poly2"); + QTest::addColumn<bool>("result"); + + QTest::newRow("empty intersects nothing") + << QPolygon() + << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10)) + << false; + QTest::newRow("identical triangles") + << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10)) + << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10)) + << true; + QTest::newRow("not intersecting") + << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(10,10) << QPoint(-10,10)) + << QPolygon(QVector<QPoint>() << QPoint(0,20) << QPoint(10,12) << QPoint(-10,12)) + << false; + QTest::newRow("clean intersection of squares") + << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(0,10) << QPoint(10,10) << QPoint(10,0)) + << QPolygon(QVector<QPoint>() << QPoint(5,5) << QPoint(5,15) << QPoint(15,15) << QPoint(15,5)) + << true; + QTest::newRow("clean contains of squares") + << QPolygon(QVector<QPoint>() << QPoint(0,0) << QPoint(0,10) << QPoint(10,10) << QPoint(10,0)) + << QPolygon(QVector<QPoint>() << QPoint(5,5) << QPoint(5,8) << QPoint(8,8) << QPoint(8,5)) + << true; +} + +void tst_QPolygon::intersections() +{ + QFETCH(QPolygon, poly1); + QFETCH(QPolygon, poly2); + QFETCH(bool, result); + + QCOMPARE(poly2.intersects(poly1), poly1.intersects(poly2)); + QCOMPARE(poly2.intersected(poly1).isEmpty(), poly1.intersected(poly2).isEmpty()); + QCOMPARE(!poly1.intersected(poly2).isEmpty(), poly1.intersects(poly2)); + QCOMPARE(poly1.intersects(poly2), result); +} + QTEST_APPLESS_MAIN(tst_QPolygon) #include "tst_qpolygon.moc" diff --git a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp index a79526c434..46420b49c5 100644 --- a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp +++ b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp @@ -118,127 +118,96 @@ void tst_QWMatrix::mapping_data() #define M_PI 3.14159265897932384626433832795f #endif + const auto rotate = [](qreal degrees) { + const qreal rad = M_PI * degrees / 180.; + return QMatrix(std::cos(rad), -std::sin(rad), + std::sin(rad), std::cos(rad), 0, 0); + }; + // rotations - float deg = 0.; - QTest::newRow( "rot 0 a" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 a" ) << rotate(0.) << QRect( 0, 0, 30, 40 ) << QPolygon ( QRect( 0, 0, 30, 40 ) ); - deg = 0.00001f; - QTest::newRow( "rot 0 b" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 b" ) << rotate(0.00001f) << QRect( 0, 0, 30, 40 ) << QPolygon ( QRect( 0, 0, 30, 40 ) ); - deg = 0.; - QTest::newRow( "rot 0 c" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 c" ) << rotate(0.) << QRect( 10, 20, 30, 40 ) << QPolygon ( QRect( 10, 20, 30, 40 ) ); - deg = 0.00001f; - QTest::newRow( "rot 0 d" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 0 d" ) << rotate(0.00001f) << QRect( 10, 20, 30, 40 ) << QPolygon ( QRect( 10, 20, 30, 40 ) ); #if 0 - // rotations - deg = 90.; - QTest::newRow( "rotscale 90 a" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + const auto rotScale = [](qreal degrees, qreal scale) { + const qreal rad = M_PI * degrees / 180.; + return QMatrix(scale * std::cos(rad), -scale * std::sin(rad), + scale * std::sin(rad), scale * std::cos(rad), 0, 0); + }; + // rotations with scaling + QTest::newRow( "rotscale 90 a" ) << rotScale(90., 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( 0, -299, 400, 300 ) ); - deg = 90.00001; - QTest::newRow( "rotscale 90 b" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 b" ) << rotScale(90.00001, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( 0, -299, 400, 300 ) ); - deg = 90.; - QTest::newRow( "rotscale 90 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 c" ) << rotScale(90., 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 200, -399, 400, 300 ) ); - deg = 90.00001; - QTest::newRow( "rotscale 90 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 90 d" ) << rotScale(90.00001, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 200, -399, 400, 300 ) ); - deg = 180.; - QTest::newRow( "rotscale 180 a" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 a" ) << rotScale(180., 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -299, -399, 300, 400 ) ); - deg = 180.000001; - QTest::newRow( "rotscale 180 b" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 b" ) << rotScale(180.000001, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -299, -399, 300, 400 ) ); - deg = 180.; - QTest::newRow( "rotscale 180 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 c" ) << rotScale(180., 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -399, -599, 300, 400 ) ); - deg = 180.000001; - QTest::newRow( "rotscale 180 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 180 d" ) << rotScale(180.000001, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -399, -599, 300, 400 ) ); - deg = 270.; - QTest::newRow( "rotscale 270 a" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 a" ) << rotScale(270., 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -399, 00, 400, 300 ) ); - deg = 270.0000001; - QTest::newRow( "rotscale 270 b" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 b" ) << rotScale(270.0000001, 10) << QRect( 0, 0, 30, 40 ) << QPolygon( QRect( -399, 00, 400, 300 ) ); - deg = 270.; - QTest::newRow( "rotscale 270 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 c" ) << rotScale(270., 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -599, 100, 400, 300 ) ); - deg = 270.000001; - QTest::newRow( "rotscale 270 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rotscale 270 d" ) << rotScale(270.000001, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -599, 100, 400, 300 ) ); // rotations that are not multiples of 90 degrees. mapRect returns the bounding rect here. - deg = 45; - QTest::newRow( "rot 45 a" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 a" ) << rotate(45) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( 0, -7, 14, 14 ) ); - QTest::newRow( "rot 45 b" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 b" ) << rotate(45) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 21, -14, 49, 49 ) ); - QTest::newRow( "rot 45 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 c" ) << rotScale(45, 10) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( 0, -70, 141, 141 ) ); - QTest::newRow( "rot 45 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot 45 d" ) << rotScale(45, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( 212, -141, 495, 495 ) ); - deg = -45; - QTest::newRow( "rot -45 a" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 a" ) << rotate(-45) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( -7, 0, 14, 14 ) ); - QTest::newRow( "rot -45 b" ) << QMatrix( std::cos( M_PI*deg/180. ), -std::sin( M_PI*deg/180. ), - std::sin( M_PI*deg/180. ), std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 b" ) << rotate(-45) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -35, 21, 49, 49 ) ); - QTest::newRow( "rot -45 c" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 c" ) << rotScale(-45, 10) << QRect( 0, 0, 10, 10 ) << QPolygon( QRect( -70, 0, 141, 141 ) ); - QTest::newRow( "rot -45 d" ) << QMatrix( 10*std::cos( M_PI*deg/180. ), -10*std::sin( M_PI*deg/180. ), - 10*std::sin( M_PI*deg/180. ), 10*std::cos( M_PI*deg/180. ), 0, 0 ) + QTest::newRow( "rot -45 d" ) << rotScale(-45, 10) << QRect( 10, 20, 30, 40 ) << QPolygon( QRect( -353, 212, 495, 495 ) ); #endif diff --git a/tests/auto/gui/qvulkan/qvulkan.pro b/tests/auto/gui/qvulkan/qvulkan.pro new file mode 100644 index 0000000000..0db990a2d6 --- /dev/null +++ b/tests/auto/gui/qvulkan/qvulkan.pro @@ -0,0 +1,9 @@ +############################################################ +# Project file for autotest for gui/vulkan functionality +############################################################ + +CONFIG += testcase +TARGET = tst_qvulkan +QT += gui-private core-private testlib + +SOURCES += tst_qvulkan.cpp diff --git a/tests/auto/gui/qvulkan/tst_qvulkan.cpp b/tests/auto/gui/qvulkan/tst_qvulkan.cpp new file mode 100644 index 0000000000..8027935003 --- /dev/null +++ b/tests/auto/gui/qvulkan/tst_qvulkan.cpp @@ -0,0 +1,435 @@ +/**************************************************************************** +** +** 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 <QtGui/QVulkanInstance> +#include <QtGui/QVulkanFunctions> +#include <QtGui/QVulkanWindow> + +#include <QtTest/QtTest> + +#include <QSignalSpy> + +class tst_QVulkan : public QObject +{ + Q_OBJECT + +private slots: + void vulkanInstance(); + void vulkanCheckSupported(); + void vulkanPlainWindow(); + void vulkanVersionRequest(); + void vulkanWindow(); + void vulkanWindowRenderer(); + void vulkanWindowGrab(); +}; + +void tst_QVulkan::vulkanInstance() +{ + QVulkanInstance inst; + if (!inst.create()) + QSKIP("Vulkan init failed; skip"); + + QVERIFY(inst.isValid()); + QVERIFY(inst.vkInstance() != VK_NULL_HANDLE); + QVERIFY(inst.functions()); + QVERIFY(!inst.flags().testFlag(QVulkanInstance::NoDebugOutputRedirect)); + + inst.destroy(); + + QVERIFY(!inst.isValid()); + QVERIFY(inst.handle() == nullptr); + + inst.setFlags(QVulkanInstance::NoDebugOutputRedirect); + // pass a bogus layer and extension + inst.setExtensions(QByteArrayList() << "abcdefg" << "notanextension"); + inst.setLayers(QByteArrayList() << "notalayer"); + QVERIFY(inst.create()); + + QVERIFY(inst.isValid()); + QVERIFY(inst.vkInstance() != VK_NULL_HANDLE); + QVERIFY(inst.handle() != nullptr); + QVERIFY(inst.functions()); + QVERIFY(inst.flags().testFlag(QVulkanInstance::NoDebugOutputRedirect)); + QVERIFY(!inst.extensions().contains("abcdefg")); + QVERIFY(!inst.extensions().contains("notanextension")); + QVERIFY(!inst.extensions().contains("notalayer")); + // at least the surface extensions should be there however + QVERIFY(inst.extensions().contains("VK_KHR_surface")); + + QVERIFY(inst.getInstanceProcAddr("vkGetDeviceQueue")); +} + +void tst_QVulkan::vulkanCheckSupported() +{ + // Test the early calls to supportedLayers/extensions that need the library + // and some basics, but do not initialize the instance. + QVulkanInstance inst; + QVERIFY(!inst.isValid()); + + QVulkanInfoVector<QVulkanLayer> vl = inst.supportedLayers(); + qDebug() << vl; + QVERIFY(!inst.isValid()); + + QVulkanInfoVector<QVulkanExtension> ve = inst.supportedExtensions(); + qDebug() << ve; + QVERIFY(!inst.isValid()); + + if (inst.create()) { // skip the rest when Vulkan is not supported at all + QVERIFY(!ve.isEmpty()); + QVERIFY(ve == inst.supportedExtensions()); + } +} + +void tst_QVulkan::vulkanPlainWindow() +{ + QVulkanInstance inst; + if (!inst.create()) + QSKIP("Vulkan init failed; skip"); + + QWindow w; + w.setSurfaceType(QSurface::VulkanSurface); + w.setVulkanInstance(&inst); + w.resize(1024, 768); + w.show(); + QTest::qWaitForWindowExposed(&w); + + QCOMPARE(w.vulkanInstance(), &inst); + + VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(&w); + QVERIFY(surface != VK_NULL_HANDLE); + + // exercise supportsPresent (and QVulkanFunctions) a bit + QVulkanFunctions *f = inst.functions(); + VkPhysicalDevice physDev; + uint32_t count = 1; + VkResult err = f->vkEnumeratePhysicalDevices(inst.vkInstance(), &count, &physDev); + if (err != VK_SUCCESS) + QSKIP("No physical devices; skip"); + + VkPhysicalDeviceProperties physDevProps; + f->vkGetPhysicalDeviceProperties(physDev, &physDevProps); + qDebug("Device name: %s Driver version: %d.%d.%d", physDevProps.deviceName, + VK_VERSION_MAJOR(physDevProps.driverVersion), VK_VERSION_MINOR(physDevProps.driverVersion), + VK_VERSION_PATCH(physDevProps.driverVersion)); + + bool supports = inst.supportsPresent(physDev, 0, &w); + qDebug("queue family 0 supports presenting to window = %d", supports); +} + +void tst_QVulkan::vulkanVersionRequest() +{ + QVulkanInstance inst; + if (!inst.create()) + QSKIP("Vulkan init failed; skip"); + + // Now that we know Vulkan is functional, check the requested apiVersion is + // passed to vkCreateInstance as expected. + + inst.destroy(); + + inst.setApiVersion(QVersionNumber(10, 0, 0)); + QVERIFY(!inst.create()); + QCOMPARE(inst.errorCode(), VK_ERROR_INCOMPATIBLE_DRIVER); +} + +static void waitForUnexposed(QWindow *w) +{ + QElapsedTimer timer; + timer.start(); + while (w->isExposed()) { + int remaining = 5000 - int(timer.elapsed()); + if (remaining <= 0) + break; + QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); + QCoreApplication::sendPostedEvents(Q_NULLPTR, QEvent::DeferredDelete); + QTest::qSleep(10); + } +} + +void tst_QVulkan::vulkanWindow() +{ + QVulkanInstance inst; + if (!inst.create()) + QSKIP("Vulkan init failed; skip"); + + // First let's forget to set the instance. + QVulkanWindow w; + QVERIFY(!w.isValid()); + w.resize(1024, 768); + w.show(); + QTest::qWaitForWindowExposed(&w); + QVERIFY(!w.isValid()); + + // Now set it. A simple hide - show should be enough to correct, this, no + // need for a full destroy - create. + w.hide(); + waitForUnexposed(&w); + w.setVulkanInstance(&inst); + QVector<VkPhysicalDeviceProperties> pdevs = w.availablePhysicalDevices(); + if (pdevs.isEmpty()) + QSKIP("No Vulkan physical devices; skip"); + w.show(); + QTest::qWaitForWindowExposed(&w); + QVERIFY(w.isValid()); + QCOMPARE(w.vulkanInstance(), &inst); + QVulkanInfoVector<QVulkanExtension> exts = w.supportedDeviceExtensions(); + + // Now destroy and recreate. + w.destroy(); + waitForUnexposed(&w); + QVERIFY(!w.isValid()); + // check that flags can be set between a destroy() - show() + w.setFlags(QVulkanWindow::PersistentResources); + // supported lists can be queried before expose too + QVERIFY(w.supportedDeviceExtensions() == exts); + w.show(); + QTest::qWaitForWindowExposed(&w); + QVERIFY(w.isValid()); + QVERIFY(w.flags().testFlag(QVulkanWindow::PersistentResources)); + + QVERIFY(w.physicalDevice() != VK_NULL_HANDLE); + QVERIFY(w.physicalDeviceProperties() != nullptr); + QVERIFY(w.device() != VK_NULL_HANDLE); + QVERIFY(w.graphicsQueue() != VK_NULL_HANDLE); + QVERIFY(w.graphicsCommandPool() != VK_NULL_HANDLE); + QVERIFY(w.defaultRenderPass() != VK_NULL_HANDLE); + + QVERIFY(w.concurrentFrameCount() > 0); + QVERIFY(w.concurrentFrameCount() <= QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT); +} + +class TestVulkanRenderer; + +class TestVulkanWindow : public QVulkanWindow +{ +public: + QVulkanWindowRenderer *createRenderer() override; + +private: + TestVulkanRenderer *m_renderer = nullptr; +}; + +struct TestVulkan { + int preInitResCount = 0; + int initResCount = 0; + int initSwcResCount = 0; + int releaseResCount = 0; + int releaseSwcResCount = 0; + int startNextFrameCount = 0; +} testVulkan; + +class TestVulkanRenderer : public QVulkanWindowRenderer +{ +public: + TestVulkanRenderer(QVulkanWindow *w) : m_window(w) { } + + void preInitResources() override; + void initResources() override; + void initSwapChainResources() override; + void releaseSwapChainResources() override; + void releaseResources() override; + + void startNextFrame() override; + +private: + QVulkanWindow *m_window; + QVulkanDeviceFunctions *m_devFuncs; +}; + +void TestVulkanRenderer::preInitResources() +{ + if (testVulkan.initResCount) { + qWarning("initResources called before preInitResources?!"); + testVulkan.preInitResCount = -1; + return; + } + + // Ensure the physical device and the surface are available at this stage. + VkPhysicalDevice physDev = m_window->physicalDevice(); + if (physDev == VK_NULL_HANDLE) { + qWarning("No physical device in preInitResources"); + testVulkan.preInitResCount = -1; + return; + } + VkSurfaceKHR surface = m_window->vulkanInstance()->surfaceForWindow(m_window); + if (surface == VK_NULL_HANDLE) { + qWarning("No surface in preInitResources"); + testVulkan.preInitResCount = -1; + return; + } + + ++testVulkan.preInitResCount; +} + +void TestVulkanRenderer::initResources() +{ + m_devFuncs = m_window->vulkanInstance()->deviceFunctions(m_window->device()); + ++testVulkan.initResCount; +} + +void TestVulkanRenderer::initSwapChainResources() +{ + ++testVulkan.initSwcResCount; +} + +void TestVulkanRenderer::releaseSwapChainResources() +{ + ++testVulkan.releaseSwcResCount; +} + +void TestVulkanRenderer::releaseResources() +{ + ++testVulkan.releaseResCount; +} + +void TestVulkanRenderer::startNextFrame() +{ + ++testVulkan.startNextFrameCount; + + VkClearColorValue clearColor = { 0, 1, 0, 1 }; + VkClearDepthStencilValue clearDS = { 1, 0 }; + VkClearValue clearValues[2]; + memset(clearValues, 0, sizeof(clearValues)); + clearValues[0].color = clearColor; + clearValues[1].depthStencil = clearDS; + + VkRenderPassBeginInfo rpBeginInfo; + memset(&rpBeginInfo, 0, sizeof(rpBeginInfo)); + rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + rpBeginInfo.renderPass = m_window->defaultRenderPass(); + rpBeginInfo.framebuffer = m_window->currentFramebuffer(); + const QSize sz = m_window->swapChainImageSize(); + rpBeginInfo.renderArea.extent.width = sz.width(); + rpBeginInfo.renderArea.extent.height = sz.height(); + rpBeginInfo.clearValueCount = 2; + rpBeginInfo.pClearValues = clearValues; + VkCommandBuffer cmdBuf = m_window->currentCommandBuffer(); + m_devFuncs->vkCmdBeginRenderPass(cmdBuf, &rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + m_devFuncs->vkCmdEndRenderPass(cmdBuf); + + m_window->frameReady(); +} + +QVulkanWindowRenderer *TestVulkanWindow::createRenderer() +{ + Q_ASSERT(!m_renderer); + m_renderer = new TestVulkanRenderer(this); + return m_renderer; +} + +void tst_QVulkan::vulkanWindowRenderer() +{ + QVulkanInstance inst; + if (!inst.create()) + QSKIP("Vulkan init failed; skip"); + + testVulkan = TestVulkan(); + + TestVulkanWindow w; + w.setVulkanInstance(&inst); + w.resize(1024, 768); + w.show(); + QTest::qWaitForWindowExposed(&w); + + if (w.availablePhysicalDevices().isEmpty()) + QSKIP("No Vulkan physical devices; skip"); + + QVERIFY(testVulkan.preInitResCount == 1); + QVERIFY(testVulkan.initResCount == 1); + QVERIFY(testVulkan.initSwcResCount == 1); + // this has to be QTRY due to the async update in QVulkanWindowPrivate::ensureStarted() + QTRY_VERIFY(testVulkan.startNextFrameCount >= 1); + + QVERIFY(!w.swapChainImageSize().isEmpty()); + QVERIFY(w.colorFormat() != VK_FORMAT_UNDEFINED); + QVERIFY(w.depthStencilFormat() != VK_FORMAT_UNDEFINED); + + w.destroy(); + waitForUnexposed(&w); + QVERIFY(testVulkan.releaseSwcResCount == 1); + QVERIFY(testVulkan.releaseResCount == 1); +} + +void tst_QVulkan::vulkanWindowGrab() +{ + QVulkanInstance inst; + inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation"); + if (!inst.create()) + QSKIP("Vulkan init failed; skip"); + + testVulkan = TestVulkan(); + + TestVulkanWindow w; + w.setVulkanInstance(&inst); + w.resize(1024, 768); + w.show(); + QTest::qWaitForWindowExposed(&w); + + if (w.availablePhysicalDevices().isEmpty()) + QSKIP("No Vulkan physical devices; skip"); + + if (!w.supportsGrab()) + QSKIP("No grab support; skip"); + + QVERIFY(!w.swapChainImageSize().isEmpty()); + + QImage img1 = w.grab(); + QImage img2 = w.grab(); + QImage img3 = w.grab(); + + QVERIFY(!img1.isNull()); + QVERIFY(!img2.isNull()); + QVERIFY(!img3.isNull()); + + QCOMPARE(img1.size(), w.swapChainImageSize()); + QCOMPARE(img2.size(), w.swapChainImageSize()); + QCOMPARE(img3.size(), w.swapChainImageSize()); + + QRgb a = img1.pixel(10, 20); + QRgb b = img2.pixel(5, 5); + QRgb c = img3.pixel(50, 30); + + QCOMPARE(a, b); + QCOMPARE(b, c); + QRgb refPixel = qRgb(0, 255, 0); + + int redFuzz = qAbs(qRed(a) - qRed(refPixel)); + int greenFuzz = qAbs(qGreen(a) - qGreen(refPixel)); + int blueFuzz = qAbs(qBlue(a) - qBlue(refPixel)); + + QVERIFY(redFuzz <= 1); + QVERIFY(blueFuzz <= 1); + QVERIFY(greenFuzz <= 1); + + w.destroy(); +} + +QTEST_MAIN(tst_QVulkan) + +#include "tst_qvulkan.moc" diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index 764b99646b..2f3da2c196 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -187,6 +187,7 @@ private slots: void cssInheritance(); void lineHeightType(); + void cssLineHeightMultiplier(); private: void backgroundImage_checkExpectedHtml(const QTextDocument &doc); void buildRegExpData(); @@ -3398,6 +3399,33 @@ void tst_QTextDocument::lineHeightType() { QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { -qt-line-height-type: fixed; line-height: 10; -qt-line-height-type: fixed; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::FixedHeight)); + QCOMPARE(format.lineHeight(), 10.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { -qt-line-height-type: proportional; line-height: 3; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::ProportionalHeight)); + QCOMPARE(format.lineHeight(), 3.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { line-height: 2.5; -qt-line-height-type: proportional; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::ProportionalHeight)); + QCOMPARE(format.lineHeight(), 2.5); + } + + { + QTextDocument td; td.setHtml("<html><head><style type=\"text/css\">body { line-height: 33; -qt-line-height-type: minimum; }</style></head><body>Foobar</body></html>"); QTextBlock block = td.begin(); QTextBlockFormat format = block.blockFormat(); @@ -3424,5 +3452,26 @@ void tst_QTextDocument::lineHeightType() } } +void tst_QTextDocument::cssLineHeightMultiplier() +{ + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { line-height: 10; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::ProportionalHeight)); + QCOMPARE(format.lineHeight(), 1000.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body {line-height: 1.38; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::ProportionalHeight)); + QCOMPARE(format.lineHeight(), 138.0); + } +} + QTEST_MAIN(tst_QTextDocument) #include "tst_qtextdocument.moc" |