summaryrefslogtreecommitdiffstats
path: root/tests/baseline
diff options
context:
space:
mode:
Diffstat (limited to 'tests/baseline')
-rw-r--r--tests/baseline/CMakeLists.txt5
-rw-r--r--tests/baseline/painting/CMakeLists.txt9
-rw-r--r--tests/baseline/painting/scripts/aliasing.qps13
-rw-r--r--tests/baseline/painting/scripts/pattern_xform.qps79
-rw-r--r--tests/baseline/painting/scripts/pattern_xform2.qps81
-rw-r--r--tests/baseline/painting/scripts/pixmapfragments.qps65
-rw-r--r--tests/baseline/painting/scripts/text.qps2
-rw-r--r--tests/baseline/painting/tst_baseline_painting.cpp27
-rw-r--r--tests/baseline/shared/baselineprotocol.cpp4
-rw-r--r--tests/baseline/shared/baselineprotocol.h2
-rw-r--r--tests/baseline/shared/lookup3.cpp8
-rw-r--r--tests/baseline/shared/paintcommands.cpp151
-rw-r--r--tests/baseline/shared/paintcommands.h14
-rw-r--r--tests/baseline/shared/qbaselinetest.cpp50
-rw-r--r--tests/baseline/shared/qbaselinetest.h9
-rw-r--r--tests/baseline/shared/qwidgetbaselinetest.cpp62
-rw-r--r--tests/baseline/shared/qwidgetbaselinetest.h4
-rw-r--r--tests/baseline/stylesheet/CMakeLists.txt6
-rw-r--r--tests/baseline/stylesheet/qss/qheaderview/selectedFontWeight.qss16
-rw-r--r--tests/baseline/stylesheet/qss/qtreeview/showDecorationSelected.qss3
-rw-r--r--tests/baseline/stylesheet/qss/qtreeview/styledSelection.qss10
-rw-r--r--tests/baseline/stylesheet/tst_baseline_stylesheet.cpp55
-rw-r--r--tests/baseline/text/CMakeLists.txt6
-rw-r--r--tests/baseline/text/data/colored_list.html68
-rw-r--r--tests/baseline/text/tst_baseline_text.cpp28
-rw-r--r--tests/baseline/widgets/CMakeLists.txt6
-rw-r--r--tests/baseline/widgets/tst_baseline_widgets.cpp197
27 files changed, 879 insertions, 101 deletions
diff --git a/tests/baseline/CMakeLists.txt b/tests/baseline/CMakeLists.txt
index df5d35863b..037ffd9e0e 100644
--- a/tests/baseline/CMakeLists.txt
+++ b/tests/baseline/CMakeLists.txt
@@ -1,4 +1,7 @@
-if(TARGET Qt::Network)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(TARGET Qt::Gui AND TARGET Qt::Network AND QT_FEATURE_pdf)
add_subdirectory(painting)
endif()
if(TARGET Qt::Network AND TARGET Qt::Widgets)
diff --git a/tests/baseline/painting/CMakeLists.txt b/tests/baseline/painting/CMakeLists.txt
index b32d8f1324..72e737d227 100644
--- a/tests/baseline/painting/CMakeLists.txt
+++ b/tests/baseline/painting/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
#####################################################################
## tst_baseline_painting Test:
#####################################################################
@@ -14,9 +17,11 @@ qt_internal_add_test(tst_baseline_painting
../shared/qbaselinetest.cpp ../shared/qbaselinetest.h
../shared/paintcommands.cpp ../shared/paintcommands.h
tst_baseline_painting.cpp
+ NO_PCH_SOURCES
+ tst_baseline_painting.cpp # undef QT_NO_FOREACH
INCLUDE_DIRECTORIES
../shared
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::GuiPrivate
Qt::Network
@@ -68,6 +73,6 @@ qt_internal_add_resource(tst_baseline_painting "images"
#####################################################################
qt_internal_extend_target(tst_baseline_painting CONDITION QT_FEATURE_opengl
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::OpenGL
)
diff --git a/tests/baseline/painting/scripts/aliasing.qps b/tests/baseline/painting/scripts/aliasing.qps
index 59878f9c4d..1fb0113396 100644
--- a/tests/baseline/painting/scripts/aliasing.qps
+++ b/tests/baseline/painting/scripts/aliasing.qps
@@ -19,6 +19,17 @@ begin_block drawing
setPen black
drawText 0 68 "QwErTy@"
+ setPen green 1 SolidLine
+ drawLine 0 75 10 75
+ setPen 800000ff 1
+ drawPoint 0 75
+ drawPoint 10 75
+
+ setPen green 2 SolidLine
+ drawLine 20 75 30 75
+ setPen 800000ff 2
+ drawPoint 20 75
+ drawPoint 30 75
setPen black 1
setBrush 7f7fff
@@ -153,4 +164,4 @@ drawText 15 185 "1.0"
resetMatrix
drawText 430 95 "Aliased"
-drawText 430 275 "Anti-Aliased" \ No newline at end of file
+drawText 430 275 "Anti-Aliased"
diff --git a/tests/baseline/painting/scripts/pattern_xform.qps b/tests/baseline/painting/scripts/pattern_xform.qps
new file mode 100644
index 0000000000..224969f1c7
--- /dev/null
+++ b/tests/baseline/painting/scripts/pattern_xform.qps
@@ -0,0 +1,79 @@
+# Version: 1
+# CheckVsReference: 5%
+
+#define basic block off screen
+save
+translate -1000 -1000
+begin_block drawrects
+setBrush green Dense4Pattern
+drawRect 0 0 40 40
+setBrush green DiagCrossPattern
+drawRect 40 0 40 40
+setBrush green HorPattern
+brushRotate 30
+drawRect 80 0 40 40
+fillRect 120 0 40 40
+save
+setPen brush 40 SolidLine FlatCap
+setBrush NoBrush
+drawLine 160 20 200 20
+restore
+end_block
+restore
+
+begin_block hintsuite
+save
+setRenderHint NonCosmeticBrushPatterns false
+setRenderHint SmoothPixmapTransform false
+translate 10 10
+repeat_block drawrects
+
+setRenderHint NonCosmeticBrushPatterns false
+setRenderHint SmoothPixmapTransform true
+translate 0 50
+repeat_block drawrects
+
+setRenderHint NonCosmeticBrushPatterns true
+setRenderHint SmoothPixmapTransform false
+translate 0 50
+repeat_block drawrects
+
+setRenderHint NonCosmeticBrushPatterns true
+setRenderHint SmoothPixmapTransform true
+translate 0 50
+repeat_block drawrects
+restore
+end_block
+
+save
+translate 0 200
+scale 2 2
+repeat_block hintsuite
+restore
+
+save
+translate 500 0
+scale 1.5 2.5
+rotate_y 60
+repeat_block hintsuite
+restore
+
+
+translate 0 650
+setBrush blue CrossPattern
+setPen red
+setRenderHint NonCosmeticBrushPatterns false
+
+begin_block dots
+save
+drawRect 0 0 50 50
+setBrushOrigin 12 0
+drawRect 50 0 50 50
+scale 2 1
+drawRect 50 0 50 50
+restore
+end_block dots
+
+setRenderHint NonCosmeticBrushPatterns true
+translate 0 60
+repeat_block dots
diff --git a/tests/baseline/painting/scripts/pattern_xform2.qps b/tests/baseline/painting/scripts/pattern_xform2.qps
new file mode 100644
index 0000000000..4f9314272d
--- /dev/null
+++ b/tests/baseline/painting/scripts/pattern_xform2.qps
@@ -0,0 +1,81 @@
+# Version: 1
+# CheckVsReference: 5%
+
+# 1: Check brush origin vs (non)cosmetic brush patterns
+
+setBrush blue CrossPattern
+begin_block blockName
+save
+setBrushOrigin 0 0
+fillRect 0 0 32 32
+translate 0 32
+setBrushOrigin 1 0
+fillRect 0 0 32 32
+translate 0 32
+setBrushOrigin 2 0
+fillRect 0 0 32 32
+translate 0 32
+setBrushOrigin 3 0
+fillRect 0 0 32 32
+translate 0 32
+setBrushOrigin 4 0
+fillRect 0 0 32 32
+translate 0 32
+setBrushOrigin 5 0
+fillRect 0 0 32 32
+translate 0 32
+setBrushOrigin 6 0
+fillRect 0 0 32 32
+translate 0 32
+setBrushOrigin 7 0
+fillRect 0 0 32 32
+translate 0 32
+setBrushOrigin 8 0
+fillRect 0 0 32 32
+restore
+end_block blockName
+
+save
+setBrush red CrossPattern
+scale 2 1
+repeat_block blockName
+restore
+
+save
+translate 0 300
+setRenderHint NonCosmeticBrushPatterns true
+setBrush blue CrossPattern
+repeat_block blockName
+setBrush red CrossPattern
+scale 2 1
+repeat_block blockName
+restore
+
+# 2: Check brush update after only xform or hint change
+translate 100 0
+
+save
+setPen NoPen
+setBrush blue DiagCrossPattern
+setRenderHint NonCosmeticBrushPatterns true
+drawRect 10 10 200 100
+scale 10 10
+drawRect 22 1 20 10
+drawRect 22 12 20 10
+setRenderHint NonCosmeticBrushPatterns false
+drawRect 1 12 20 10
+restore
+
+setBrush green DiagCrossPattern
+setPen brush 100 SolidLine FlatCap
+pen_setCosmetic true
+setBrush NoBrush
+translate 0 250
+setRenderHint NonCosmeticBrushPatterns true
+drawLine 10 60 210 60
+scale 10 10
+drawLine 22 6 42 6
+drawLine 22 17 42 17
+setRenderHint NonCosmeticBrushPatterns false
+drawLine 1 17 21 17
+
diff --git a/tests/baseline/painting/scripts/pixmapfragments.qps b/tests/baseline/painting/scripts/pixmapfragments.qps
new file mode 100644
index 0000000000..4c837b760f
--- /dev/null
+++ b/tests/baseline/painting/scripts/pixmapfragments.qps
@@ -0,0 +1,65 @@
+# Version: 1
+# CheckVsReference: 1% (0 0 690 580)
+
+
+setRenderHint Antialiasing
+
+setPen #00ff00
+
+pixmap_load dome_argb32.png the_pixmap
+begin_block draw_stuff
+save
+ drawPixmapFragments the_pixmap 1 50 50 25 25 60 60 1 1 0 1
+ drawPixmapFragments the_pixmap 1 150 50 25 25 60 60 1 1 0 0.5
+ drawPixmapFragments the_pixmap 1 250 50 25 25 60 60 1 1 30 1
+ drawPixmapFragments the_pixmap 1 350 50 25 25 60 60 1.5 1 0 1
+ drawPixmapFragments the_pixmap 1 450 50 25 25 60 60 1 1.5 0 1
+ drawPixmapFragments the_pixmap 2 550 50 25 25 40 40 0.5 0.5 -45 1 600 50 25 25 40 40 0.7 0.7 45 1
+restore
+end_block
+
+
+translate 0 120
+pixmap_load dome_rgb32.png the_pixmap
+repeat_block draw_stuff
+
+translate 0 120
+pixmap_load dome_indexed.png the_pixmap
+repeat_block draw_stuff
+
+translate 0 120
+pixmap_load dome_indexed_mask.png the_pixmap
+repeat_block draw_stuff
+
+translate 0 120
+pixmap_load dome_mono.png the_pixmap
+repeat_block draw_stuff
+
+
+resetMatrix
+translate 700 60
+setPen black
+drawText 0 0 "32 bit w/alpha"
+translate 0 120
+drawText 0 0 "32 bit w/o alpha"
+translate 0 120
+drawText 0 0 "8 bit indexed"
+translate 0 120
+drawText 0 0 "8 bit indexed w/mask"
+translate 0 120
+drawText 0 0 "1 bit"
+
+resetMatrix
+translate 25 600
+drawText 0 0 "simple"
+translate 100 0
+drawText 0 0 "opacity"
+translate 100 0
+drawText 0 0 "rotation"
+translate 100 0
+drawText 0 0 "scale x"
+translate 100 0
+drawText 0 0 "scale y"
+translate 100 0
+drawText 0 0 "two fragments"
+translate 100 0
diff --git a/tests/baseline/painting/scripts/text.qps b/tests/baseline/painting/scripts/text.qps
index 4d81b3084c..6bacdfd5e6 100644
--- a/tests/baseline/painting/scripts/text.qps
+++ b/tests/baseline/painting/scripts/text.qps
@@ -165,7 +165,7 @@ translate 0 75
save
setPen black
setFont "sansserif" 16 normal
- drawText 0 40 "e😃m😇o😍j😜i😸!"
+ drawText 0 40 "e😃m😇o😍j😜i😸!✈️"
restore
translate 0 75
diff --git a/tests/baseline/painting/tst_baseline_painting.cpp b/tests/baseline/painting/tst_baseline_painting.cpp
index fe340e80e6..f486b33430 100644
--- a/tests/baseline/painting/tst_baseline_painting.cpp
+++ b/tests/baseline/painting/tst_baseline_painting.cpp
@@ -1,5 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
#include "paintcommands.h"
#include <qbaselinetest.h>
@@ -52,7 +54,7 @@ private:
private slots:
void initTestCase();
- void cleanupTestCase() {}
+ void init();
void testRasterARGB32PM_data();
void testRasterARGB32PM();
@@ -120,7 +122,7 @@ void tst_Lancelot::initTestCase()
std::sort(qpsFiles.begin(), qpsFiles.end());
foreach (const QString& fileName, qpsFiles) {
QFile file(scriptsDir + fileName);
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
QByteArray cont = file.readAll();
scripts.insert(fileName, QString::fromUtf8(cont).split(QLatin1Char('\n'), Qt::SkipEmptyParts));
scriptChecksums.insert(fileName, qChecksum(cont));
@@ -131,6 +133,11 @@ void tst_Lancelot::initTestCase()
#endif
}
+void tst_Lancelot::init()
+{
+ // This gets called for every row. QSKIP if current item is blacklisted on the baseline server:
+ QBASELINE_SKIP_IF_BLACKLISTED;
+}
void tst_Lancelot::testRasterARGB32PM_data()
{
@@ -416,19 +423,22 @@ void tst_Lancelot::runTestSuite(GraphicsEngine engine, QImage::Format format, co
QString tempStem(QDir::tempPath() + QLatin1String("/lancelot_XXXXXX_") + qpsFile.chopped(4));
QTemporaryFile pdfFile(tempStem + QLatin1String(".pdf"));
- pdfFile.open();
+ QVERIFY(pdfFile.open());
QPdfWriter writer(&pdfFile);
writer.setPdfVersion(QPdfWriter::PdfVersion_1_6);
- writer.setResolution(150);
+ QPageSize pageSize(QSize(800, 800), QStringLiteral("LancePage"), QPageSize::ExactMatch);
+ writer.setPageSize(pageSize);
+ writer.setPageMargins(QMarginsF());
+ writer.setResolution(72);
paint(&writer, engine, format, script, QFileInfo(filePath).absoluteFilePath());
pdfFile.close();
// Convert pdf to something we can read into a QImage, using macOS' sips utility
QTemporaryFile pngFile(tempStem + QLatin1String(".png"));
- pngFile.open(); // Just create the file name
+ QVERIFY(pngFile.open()); // Just create the file name
pngFile.close();
QProcess proc;
- const char *rawArgs = "-s format png --cropOffset 20 20 -c 800 800 -o";
+ const char *rawArgs = "-s format png -o";
QStringList argList = QString::fromLatin1(rawArgs).split(QLatin1Char(' '));
proc.start(QLatin1String("sips"), argList << pngFile.fileName() << pdfFile.fileName());
proc.waitForFinished(2 * 60 * 1000); // May need some time
@@ -469,7 +479,8 @@ QTEST_MAIN(tst_Lancelot)
int main(int argc, char *argv[])
{
- qSetGlobalQHashSeed(0); // Avoid rendering variations caused by QHash randomization
+ // Avoid rendering variations caused by QHash randomization
+ QHashSeed::setDeterministicGlobalSeed();
QBaselineTest::handleCmdLineArgs(&argc, &argv);
return _realmain(argc, argv);
diff --git a/tests/baseline/shared/baselineprotocol.cpp b/tests/baseline/shared/baselineprotocol.cpp
index 198057abe6..6a38e71831 100644
--- a/tests/baseline/shared/baselineprotocol.cpp
+++ b/tests/baseline/shared/baselineprotocol.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "baselineprotocol.h"
#include <QLibraryInfo>
#include <QImage>
@@ -270,7 +270,7 @@ bool BaselineProtocol::connect(const QString &testCase, bool *dryrun, const Plat
socket.connectToHost(serverName, ServerPort);
if (!socket.waitForConnected(Timeout)) {
- QThread::msleep(3000); // Wait a bit and try again, the server might just be restarting
+ QThread::sleep(std::chrono::seconds{3}); // Wait a bit and try again, the server might just be restarting
if (!socket.waitForConnected(Timeout)) {
errMsg += QLS("TCP connectToHost failed. Host:") + QLS(serverName) + QLS(" port:") + QString::number(ServerPort);
return false;
diff --git a/tests/baseline/shared/baselineprotocol.h b/tests/baseline/shared/baselineprotocol.h
index 4696900d91..598a0cd3af 100644
--- a/tests/baseline/shared/baselineprotocol.h
+++ b/tests/baseline/shared/baselineprotocol.h
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef BASELINEPROTOCOL_H
#define BASELINEPROTOCOL_H
diff --git a/tests/baseline/shared/lookup3.cpp b/tests/baseline/shared/lookup3.cpp
index 33d27bd964..7964a184ae 100644
--- a/tests/baseline/shared/lookup3.cpp
+++ b/tests/baseline/shared/lookup3.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
/*
@@ -303,7 +303,7 @@ quint32 hashlittle( const void *key, size_t length, quint32 initval)
* rest of the string. Every machine with memory protection I've seen
* does it on word boundaries, so is OK with this. But VALGRIND will
* still catch it and complain. The masking trick does make the hash
- * noticably faster for short strings (like English words).
+ * noticeably faster for short strings (like English words).
*/
#ifndef VALGRIND
@@ -511,7 +511,7 @@ void hashlittle2(
* rest of the string. Every machine with memory protection I've seen
* does it on word boundaries, so is OK with this. But VALGRIND will
* still catch it and complain. The masking trick does make the hash
- * noticably faster for short strings (like English words).
+ * noticeably faster for short strings (like English words).
*/
#ifndef VALGRIND
@@ -711,7 +711,7 @@ quint32 hashbig( const void *key, size_t length, quint32 initval)
* rest of the string. Every machine with memory protection I've seen
* does it on word boundaries, so is OK with this. But VALGRIND will
* still catch it and complain. The masking trick does make the hash
- * noticably faster for short strings (like English words).
+ * noticeably faster for short strings (like English words).
*/
#ifndef VALGRIND
diff --git a/tests/baseline/shared/paintcommands.cpp b/tests/baseline/shared/paintcommands.cpp
index daf58a7c2e..20201b66b0 100644
--- a/tests/baseline/shared/paintcommands.cpp
+++ b/tests/baseline/shared/paintcommands.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "paintcommands.h"
#include <qdir.h>
@@ -173,6 +173,13 @@ const char *PaintCommands::imageFormatTable[] = {
"RGBx32FPx4",
"RGBA32FPx4",
"RGBA32FPx4_Premultiplied",
+ "CMYK32",
+};
+
+const char *PaintCommands::renderHintTable[] = {
+ "Antialiasing",
+ "SmoothPixmapTransform",
+ "NonCosmeticBrushPatterns"
};
int PaintCommands::translateEnum(const char *table[], const QString &pattern, int limit)
@@ -313,7 +320,7 @@ void PaintCommands::staticInit()
"pen_setCosmetic true");
DECL_PAINTCOMMAND("setRenderHint", command_setRenderHint,
"^setRenderHint\\s+([\\w_0-9]*)\\s*(\\w*)$",
- "setRenderHint <Antialiasing|SmoothPixmapTransform> <true|false>",
+ "setRenderHint <hint> <true|false>",
"setRenderHint Antialiasing true");
DECL_PAINTCOMMAND("clearRenderHint", command_clearRenderHint,
"^clearRenderHint$",
@@ -463,6 +470,20 @@ void PaintCommands::staticInit()
"^fillRectF\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s+(-?[.\\w]*)\\s*(\\w*)?$",
"fillRectF <x> <y> <w> <h> [color]\n - Uses current brush if no color given",
"fillRectF 10.5 10.5 20.2 20.2 blue");
+ DECL_PAINTCOMMAND("drawPixmapFragments", command_drawPixmapFragments,
+ "^drawPixmapFragments\\s+([\\w.:\\/]*)"
+ "\\s+(-?\\w*)"
+ "\\s+(-?[.\\w]*)\\s*(-?[.\\w]*)"
+ "\\s+(-?[.\\w]*)\\s*(-?[.\\w]*)\\s*(-?[.\\w]*)\\s*(-?[.\\w]*)"
+ "\\s+(-?[.\\w]*)\\s*(-?[.\\w]*)\\s*(-?[.\\w]*)\\s*(-?[.\\w]*)"
+ "\\s*(-?[.\\w]*)?\\s*(-?[.\\w]*)?"
+ "\\s*(-?[.\\w]*)?\\s*(-?[.\\w]*)?\\s*(-?[.\\w]*)?\\s*(-?[.\\w]*)?"
+ "\\s*(-?[.\\w]*)?\\s*(-?[.\\w]*)\\s*(-?[.\\w]*)?\\s*(-?[.\\w]*)?$",
+ "drawPixmapFragments <image filename> <count>"
+ " <centerx0> <centery0> <x0> <y0> <w0> <h0> <sx0> <sy0> <r0> <o0>"
+ " <centerx1> <centery1> <x1> <y1> <w1> ..."
+ "\n - where count is 1 or 2, and followed by centerPos, sourceRect, scaleX, scaleY, rotation, opacity <count> times",
+ "drawPixmapFragments :/images/sign.png 1 50 50 10 10 60 60 10 10 30 1");
DECL_PAINTCOMMANDSECTION("painterPaths");
DECL_PAINTCOMMAND("path_moveTo", command_path_moveTo,
@@ -665,6 +686,7 @@ void PaintCommands::staticInit()
ADD_ENUMLIST("image formats", imageFormatTable);
ADD_ENUMLIST("coordinate modes", coordinateMethodTable);
ADD_ENUMLIST("size modes", sizeModeTable);
+ ADD_ENUMLIST("render hints", renderHintTable);
}
#undef DECL_PAINTCOMMAND
@@ -724,8 +746,8 @@ void PaintCommands::runCommand(const QString &scriptLine)
return;
}
QString firstWord = scriptLine.section(separators, 0, 0);
- QList<int> indices = s_commandHash.values(firstWord);
- foreach(int idx, indices) {
+ const QList<int> indices = s_commandHash.values(firstWord);
+ for (int idx : indices) {
PaintCommandInfos command = s_commandInfoTable.at(idx);
Q_ASSERT(command.regExp.isValid());
QRegularExpressionMatch match = command.regExp.match(scriptLine);
@@ -900,7 +922,7 @@ void PaintCommands::command_import(QRegularExpressionMatch re)
if (m_verboseMode) {
printf(" -(lance) Command buffer now looks like:\n");
- for (int i = 0; i < m_commands.count(); ++i)
+ for (int i = 0; i < m_commands.size(); ++i)
printf(" ---> {%s}\n", qPrintable(m_commands.at(i)));
}
delete file;
@@ -918,7 +940,7 @@ void PaintCommands::command_begin_block(QRegularExpressionMatch re)
m_commands[m_currentCommandIndex] = QLatin1String("# begin block (") + blockName + QLatin1Char(')');
QStringList newBlock;
int i = m_currentCommandIndex + 1;
- for (; i < m_commands.count(); ++i) {
+ for (; i < m_commands.size(); ++i) {
const QString &nextCmd = m_commands.at(i);
if (nextCmd.startsWith("end_block")) {
m_commands[i] = QLatin1String("# end block (") + blockName + QLatin1Char(')');
@@ -928,10 +950,10 @@ void PaintCommands::command_begin_block(QRegularExpressionMatch re)
}
if (m_verboseMode)
- for (int j = 0; j < newBlock.count(); ++j)
+ for (int j = 0; j < newBlock.size(); ++j)
printf(" %d: %s\n", j, qPrintable(newBlock.at(j)));
- if (i >= m_commands.count())
+ if (i >= m_commands.size())
printf(" - Warning! Block doesn't have an 'end_block' marker!\n");
m_blockMap.insert(blockName, newBlock);
@@ -1445,6 +1467,93 @@ void PaintCommands::command_fillRectF(QRegularExpressionMatch re)
}
}
+void PaintCommands::command_drawPixmapFragments(QRegularExpressionMatch re)
+{
+ QPixmap pm;
+ pm = m_pixmapMap[re.captured(1)]; // try cache first
+ if (pm.isNull())
+ pm = image_load<QPixmap>(re.captured(1));
+ if (pm.isNull()) {
+ QFileInfo fi(m_filepath);
+ QDir dir = fi.absoluteDir();
+ dir.cdUp();
+ dir.cd("images");
+ QString fileName = dir.absolutePath() + QLatin1Char('/') + re.captured(1);
+ pm = QPixmap(fileName);
+ if (pm.isNull() && !fileName.endsWith(".png")) {
+ fileName.append(".png");
+ pm = QPixmap(fileName);
+ }
+ }
+ if (pm.isNull()) {
+ fprintf(stderr, "ERROR(drawPixmapFragments): failed to load pixmap: '%s'\n",
+ qPrintable(re.captured(1)));
+ return;
+ }
+
+ int count = convertToInt(re.captured(2));
+
+ struct Fragment {
+ double posx;
+ double posy;
+ double srcx;
+ double srcy;
+ double srcw;
+ double srch;
+ double sx;
+ double sy;
+ double rotation;
+ double opacity;
+ };
+
+ QList<Fragment> fragments;
+ for (int i = 0; i < count; ++i) {
+ int captureIndexStart = 3 + i * 10;
+ if (re.hasCaptured(captureIndexStart)) {
+ Fragment f;
+ f.posx = convertToDouble(re.captured(captureIndexStart));
+ f.posy = convertToDouble(re.captured(captureIndexStart + 1));
+ f.srcx = convertToDouble(re.captured(captureIndexStart + 2));
+ f.srcy = convertToDouble(re.captured(captureIndexStart + 3));
+ f.srcw = convertToDouble(re.captured(captureIndexStart + 4));
+ f.srch = convertToDouble(re.captured(captureIndexStart + 5));
+ f.sx = convertToDouble(re.captured(captureIndexStart + 6));
+ f.sy = convertToDouble(re.captured(captureIndexStart + 7));
+ f.rotation = convertToDouble(re.captured(captureIndexStart + 8));
+ f.opacity = convertToDouble(re.captured(captureIndexStart + 9));
+ fragments.append(f);
+ } else {
+ break;
+ }
+ }
+
+ if (m_verboseMode) {
+ printf(" -(lance) drawPixmapFragments('%s' count=%d ",
+ qPrintable(re.captured(1)), int(fragments.count()));
+ for (int i = 0; i < fragments.count(); ++i) {
+ printf("pos=(%.2f, %.2f) srcrect=(%.2f %.2f %.2f %.2f) scale=(%.2f %.2f) rotation=%.2f opacity=%.2f ",
+ fragments[i].posx, fragments[i].posy,
+ fragments[i].srcx, fragments[i].srcy, fragments[i].srcw, fragments[i].srch,
+ fragments[i].sx, fragments[i].sy,
+ fragments[i].rotation,
+ fragments[i].opacity);
+ }
+ printf("\n");
+ }
+
+ QList<QPainter::PixmapFragment> pixmapFragments;
+ for (int i = 0; i < fragments.count(); ++i) {
+ pixmapFragments.append(
+ QPainter::PixmapFragment::create(QPointF(fragments[i].posx, fragments[i].posy),
+ QRectF(fragments[i].srcx, fragments[i].srcy, fragments[i].srcw, fragments[i].srch),
+ fragments[i].sx, fragments[i].sy,
+ fragments[i].rotation,
+ fragments[i].opacity));
+ }
+
+ m_painter->drawPixmapFragments(pixmapFragments.constData(), pixmapFragments.count(), pm);
+}
+
/***************************************************************************************************/
void PaintCommands::command_noop(QRegularExpressionMatch)
{
@@ -2240,18 +2349,27 @@ void PaintCommands::command_setPen2(QRegularExpressionMatch re)
void PaintCommands::command_setRenderHint(QRegularExpressionMatch re)
{
QString hintString = re.captured(1).toLower();
- bool on = re.captured(2).isEmpty() || re.captured(2).toLower() == "true";
- if (hintString.contains("antialiasing")) {
- if (m_verboseMode)
- printf(" -(lance) setRenderHint Antialiasing\n");
+ QString setting = re.captured(2).toLower();
- m_painter->setRenderHint(QPainter::Antialiasing, on);
+ bool on = setting.isEmpty() || setting == "true" || setting == "on";
+ QPainter::RenderHint hint;
+ int hintIdx = -1;
+ if (hintString.contains("antialiasing")) {
+ hintIdx = 0;
+ hint = QPainter::Antialiasing;
} else if (hintString.contains("smoothpixmaptransform")) {
+ hintIdx = 1;
+ hint = QPainter::SmoothPixmapTransform;
+ } else if (hintString.contains("noncosmeticbrushpatterns")) {
+ hintIdx = 2;
+ hint = QPainter::NonCosmeticBrushPatterns;
+ }
+ if (hintIdx >= 0) {
if (m_verboseMode)
- printf(" -(lance) setRenderHint SmoothPixmapTransform\n");
- m_painter->setRenderHint(QPainter::SmoothPixmapTransform, on);
+ printf(" -(lance) setRenderHint %s %s\n", renderHintTable[hintIdx], on ? "true" : "false");
+ m_painter->setRenderHint(hint, on);
} else {
- fprintf(stderr, "ERROR(setRenderHint): unknown hint '%s'\n", qPrintable(hintString));
+ fprintf(stderr, "ERROR(setRenderHint): unknown hint '%s'\n", qPrintable(re.captured(1)));
}
}
@@ -2260,6 +2378,7 @@ void PaintCommands::command_clearRenderHint(QRegularExpressionMatch /*re*/)
{
m_painter->setRenderHint(QPainter::Antialiasing, false);
m_painter->setRenderHint(QPainter::SmoothPixmapTransform, false);
+ m_painter->setRenderHint(QPainter::NonCosmeticBrushPatterns, false);
if (m_verboseMode)
printf(" -(lance) clearRenderHint\n");
}
diff --git a/tests/baseline/shared/paintcommands.h b/tests/baseline/shared/paintcommands.h
index 75f48d3eb7..45f78f9af6 100644
--- a/tests/baseline/shared/paintcommands.h
+++ b/tests/baseline/shared/paintcommands.h
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef PAINTCOMMANDS_H
#define PAINTCOMMANDS_H
@@ -43,15 +43,13 @@ class PaintCommands
{
public:
// construction / initialization
- PaintCommands(const QStringList &cmds, int w, int h, QImage::Format format)
+ PaintCommands(const QStringList &cmds, int /*w*/, int /*h*/, QImage::Format format)
: m_painter(0)
, m_surface_painter(0)
, m_format(format)
, m_commands(cmds)
, m_gradientSpread(QGradient::PadSpread)
, m_gradientCoordinate(QGradient::LogicalMode)
- , m_width(w)
- , m_height(h)
, m_verboseMode(false)
, m_type(WidgetType)
, m_checkers_background(true)
@@ -62,7 +60,9 @@ public:
, m_surface_glbuffer(0)
, m_surface_glpaintdevice(0)
#endif
- { staticInit(); }
+ {
+ staticInit();
+ }
public:
void setCheckersBackground(bool b) { staticInit(); m_checkers_background = b; }
@@ -183,6 +183,7 @@ private:
void command_drawTiledPixmap(QRegularExpressionMatch re);
void command_fillRect(QRegularExpressionMatch re);
void command_fillRectF(QRegularExpressionMatch re);
+ void command_drawPixmapFragments(QRegularExpressionMatch re);
// paths
void command_path_addEllipse(QRegularExpressionMatch re);
@@ -251,8 +252,6 @@ private:
QGradient::Spread m_gradientSpread;
QGradient::CoordinateMode m_gradientCoordinate;
bool m_abort;
- int m_width;
- int m_height;
bool m_verboseMode;
DeviceType m_type;
@@ -280,6 +279,7 @@ private:
static const char *compositionModeTable[];
static const char *imageFormatTable[];
static const char *sizeModeTable[];
+ static const char *renderHintTable[];
static int translateEnum(const char *table[], const QString &pattern, int limit);
// utility
diff --git a/tests/baseline/shared/qbaselinetest.cpp b/tests/baseline/shared/qbaselinetest.cpp
index 95da71d9e7..e41b8d5321 100644
--- a/tests/baseline/shared/qbaselinetest.cpp
+++ b/tests/baseline/shared/qbaselinetest.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qbaselinetest.h"
#include "baselineprotocol.h"
@@ -139,7 +139,7 @@ void fetchCustomClientProperties()
key = line.left(colonPos).simplified().replace(' ', '_');
val = line.mid(colonPos+1).trimmed();
}
- if (!key.isEmpty() && key.length() < 64 && val.length() < 256) // ###TBD: maximum 256 chars in value?
+ if (!key.isEmpty() && key.size() < 64 && val.size() < 256) // ###TBD: maximum 256 chars in value?
addClientProperty(key, val);
else
qDebug() << "Unparseable script output ignored:" << line;
@@ -249,6 +249,7 @@ void modifyImage(QImage *img)
bool compareItem(const ImageItem &baseline, const QImage &img, QByteArray *msg, bool *error)
{
+ *error = false;
ImageItem item = baseline;
if (simfail) {
// Simulate test failure by forcing image mismatch; for testing purposes
@@ -259,6 +260,7 @@ bool compareItem(const ImageItem &baseline, const QImage &img, QByteArray *msg,
} else {
item.image = img;
}
+ bool isNewItem = false;
item.imageChecksums.clear();
item.imageChecksums.prepend(ImageItem::computeChecksum(item.image));
QByteArray srvMsg;
@@ -270,9 +272,11 @@ bool compareItem(const ImageItem &baseline, const QImage &img, QByteArray *msg,
return true;
break;
case ImageItem::BaselineNotFound:
- if (!customInfo.overrides().isEmpty() || baselinePolicy == UploadNone) {
- qWarning() << "Cannot compare to baseline: No such baseline found on server.";
+ if (!customInfo.overrides().isEmpty())
return true;
+ if (baselinePolicy == UploadNone) {
+ isNewItem = true;
+ break;
}
if (proto.submitNewBaseline(item, &srvMsg))
qDebug() << msg->constData() << "Baseline not found on server. New baseline uploaded.";
@@ -285,7 +289,6 @@ bool compareItem(const ImageItem &baseline, const QImage &img, QByteArray *msg,
return true;
break;
}
- *error = false;
// The actual comparison of the given image with the baseline:
if (baseline.imageChecksums.contains(item.imageChecksums.at(0))) {
if (!proto.submitMatch(item, &srvMsg))
@@ -306,7 +309,11 @@ bool compareItem(const ImageItem &baseline, const QImage &img, QByteArray *msg,
qInfo() << "Baseline server reports:" << srvMsg;
return true; // The server decides: a fuzzy match means no mismatch
}
- *msg += "Mismatch. See report:\n " + srvMsg;
+ if (isNewItem)
+ *msg += "No baseline on server, so cannot compare.";
+ else
+ *msg += "Mismatch.";
+ *msg += " See report:\n " + srvMsg;
if (dryRunMode) {
qDebug() << "Dryrun, so ignoring" << *msg;
return true;
@@ -372,22 +379,21 @@ QTestData &newRow(const char *dataTag, quint16 checksum)
return QTest::newRow(dataTag);
}
-
-bool testImage(const QImage& img, QByteArray *msg, bool *error)
+const ImageItem *findCurrentItem(QByteArray *msg, bool *error)
{
if (!connected && !connect(msg, error))
- return true;
+ return nullptr;
if (QTest::currentTestFunction() != curFunction || itemList.isEmpty()) {
- qWarning() << "Usage error: QBASELINE_TEST used without corresponding QBaselineTest::newRow()";
- return true;
+ qWarning() << "Usage error: QBASELINE_ macro used without corresponding QBaselineTest::newRow()";
+ return nullptr;
}
if (!gotBaselines) {
if (!proto.requestBaselineChecksums(QString::fromLatin1(QTest::currentTestFunction()), &itemList) || itemList.isEmpty()) {
*msg = "Communication with baseline server failed: " + proto.errorMessage().toLatin1();
*error = true;
- return true;
+ return nullptr;
}
gotBaselines = true;
}
@@ -397,10 +403,24 @@ bool testImage(const QImage& img, QByteArray *msg, bool *error)
while (it != itemList.constEnd() && it->itemName != curTag)
++it;
if (it == itemList.constEnd()) {
- qWarning() << "Usage error: QBASELINE_TEST used without corresponding QBaselineTest::newRow() for row" << curTag;
- return true;
+ qWarning() << "Usage error: QBASELINE_ macro used without corresponding QBaselineTest::newRow() for row" << curTag;
+ return nullptr;
}
- return compareItem(*it, img, msg, error);
+ return &(*it);
+}
+
+bool testImage(const QImage &img, QByteArray *msg, bool *error)
+{
+ const ImageItem *item = findCurrentItem(msg, error);
+ return item ? compareItem(*item, img, msg, error) : true;
+}
+
+bool isCurrentItemBlacklisted()
+{
+ QByteArray msg;
+ bool error = false;
+ const ImageItem *item = findCurrentItem(&msg, &error);
+ return item ? (item->status == ImageItem::IgnoreItem) : false;
}
}
diff --git a/tests/baseline/shared/qbaselinetest.h b/tests/baseline/shared/qbaselinetest.h
index 2d605b0e2b..f120e2bcd8 100644
--- a/tests/baseline/shared/qbaselinetest.h
+++ b/tests/baseline/shared/qbaselinetest.h
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef BASELINETEST_H
#define BASELINETEST_H
@@ -18,6 +18,7 @@ bool connectToBaselineServer(QByteArray *msg = nullptr);
bool checkImage(const QImage& img, const char *name, quint16 checksum, QByteArray *msg, bool *error, int manualdatatag = 0);
bool testImage(const QImage& img, QByteArray *msg, bool *error);
QTestData &newRow(const char *dataTag, quint16 checksum = 0);
+bool isCurrentItemBlacklisted();
bool disconnectFromBaselineServer();
bool shouldAbortIfUnstable();
}
@@ -59,4 +60,10 @@ do {\
}\
} while (0)
+#define QBASELINE_SKIP_IF_BLACKLISTED \
+do {\
+ if (QBaselineTest::isCurrentItemBlacklisted())\
+ QSKIP("Blacklisted on baseline server.");\
+} while (0)
+
#endif // BASELINETEST_H
diff --git a/tests/baseline/shared/qwidgetbaselinetest.cpp b/tests/baseline/shared/qwidgetbaselinetest.cpp
index 5c4e7728ea..72a074e268 100644
--- a/tests/baseline/shared/qwidgetbaselinetest.cpp
+++ b/tests/baseline/shared/qwidgetbaselinetest.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qwidgetbaselinetest.h"
@@ -9,6 +9,8 @@
#include <QStyleHints>
#include <QScreen>
+#include <QtWidgets/private/qapplication_p.h>
+
QT_BEGIN_NAMESPACE
QWidgetBaselineTest::QWidgetBaselineTest()
@@ -75,11 +77,15 @@ void QWidgetBaselineTest::initTestCase()
void QWidgetBaselineTest::init()
{
QVERIFY(!window);
- window = new QWidget;
+ background = new QWidget(nullptr, Qt::FramelessWindowHint);
+ window = new QWidget(background, Qt::Window);
window->setWindowTitle(QTest::currentDataTag());
+ window->setFocusPolicy(Qt::StrongFocus);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ background->setScreen(QGuiApplication::primaryScreen());
window->setScreen(QGuiApplication::primaryScreen());
#endif
+ background->move(QGuiApplication::primaryScreen()->availableGeometry().topLeft());
window->move(QGuiApplication::primaryScreen()->availableGeometry().topLeft());
doInit();
@@ -89,19 +95,21 @@ void QWidgetBaselineTest::cleanup()
{
doCleanup();
- delete window;
+ delete background;
+ background = nullptr;
window = nullptr;
}
void QWidgetBaselineTest::makeVisible()
{
Q_ASSERT(window);
+ background->showMaximized();
window->show();
- QApplication::setActiveWindow(window);
+ QApplicationPrivate::setActiveWindow(window);
QVERIFY(QTest::qWaitForWindowActive(window));
- // explicitly unset focus, the test needs to control when focus is shown
- if (window->focusWidget())
- window->focusWidget()->clearFocus();
+ // explicitly set focus on the window so that the test widget doesn't have it
+ window->setFocus(Qt::OtherFocusReason);
+ QTRY_COMPARE(window->focusWidget(), window);
}
/*
@@ -115,6 +123,20 @@ QImage QWidgetBaselineTest::takeSnapshot()
return window->grab().toImage();
}
+/*
+ Grabs the test window screen and returns the resulting QImage, without
+ compensating for DPR differences.
+ This can be used for popup windows.
+*/
+QImage QWidgetBaselineTest::takeScreenSnapshot(const QRect& windowRect)
+{
+ // make sure all effects are done - wait longer here because entire
+ // windows might be fading in and out.
+ QTest::qWait(750);
+ return window->screen()->grabWindow(0, windowRect.x(), windowRect.y(),
+ windowRect.width(), windowRect.height()).toImage();
+}
+
/*!
Sets standard widget properties on the test window and its children,
and uploads snapshots. The widgets are returned in the same state
@@ -125,23 +147,25 @@ QImage QWidgetBaselineTest::takeSnapshot()
void QWidgetBaselineTest::takeStandardSnapshots()
{
makeVisible();
- struct PublicWidget : QWidget {
- bool focusNextPrevChild(bool next) override { return QWidget::focusNextPrevChild(next); }
- };
+ QWidget *oldFocusWidget = testWindow()->focusWidget();
+ QCOMPARE(oldFocusWidget, testWindow());
QBASELINE_CHECK_DEFERRED(takeSnapshot(), "default");
// try hard to set focus
- static_cast<PublicWidget*>(window)->focusNextPrevChild(true);
- if (!window->focusWidget()) {
- QWidget *firstChild = window->findChild<QWidget*>();
- if (firstChild)
- firstChild->setFocus();
- }
-
- if (testWindow()->focusWidget()) {
+ QWidget *testWidget = window->nextInFocusChain();
+ if (!testWidget)
+ testWidget = window->findChild<QWidget*>();
+ QVERIFY(testWidget);
+ // use TabFocusReason, some widgets handle that specifically to e.g. select
+ testWidget->setFocus(Qt::TabFocusReason);
+
+ if (testWindow()->focusWidget() != oldFocusWidget) {
QBASELINE_CHECK_DEFERRED(takeSnapshot(), "focused");
- testWindow()->focusWidget()->clearFocus();
+ // set focus back
+ oldFocusWidget->setFocus(Qt::OtherFocusReason);
+ } else {
+ qWarning() << "Couldn't set focus on tested widget" << testWidget;
}
// this disables all children
diff --git a/tests/baseline/shared/qwidgetbaselinetest.h b/tests/baseline/shared/qwidgetbaselinetest.h
index 9b96ea0a1a..2142217c09 100644
--- a/tests/baseline/shared/qwidgetbaselinetest.h
+++ b/tests/baseline/shared/qwidgetbaselinetest.h
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#pragma once
@@ -32,8 +32,10 @@ private slots:
protected:
void makeVisible();
QImage takeSnapshot();
+ QImage takeScreenSnapshot(const QRect& rect = QRect());
private:
+ QWidget *background = nullptr;
QWidget *window = nullptr;
};
diff --git a/tests/baseline/stylesheet/CMakeLists.txt b/tests/baseline/stylesheet/CMakeLists.txt
index 11f6e52179..3fdaa739fe 100644
--- a/tests/baseline/stylesheet/CMakeLists.txt
+++ b/tests/baseline/stylesheet/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
qss/*)
@@ -11,9 +14,10 @@ qt_internal_add_test(tst_baseline_stylesheet
tst_baseline_stylesheet.cpp
INCLUDE_DIRECTORIES
../shared
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
Qt::Network
TESTDATA ${test_data}
)
diff --git a/tests/baseline/stylesheet/qss/qheaderview/selectedFontWeight.qss b/tests/baseline/stylesheet/qss/qheaderview/selectedFontWeight.qss
new file mode 100644
index 0000000000..1c45a99767
--- /dev/null
+++ b/tests/baseline/stylesheet/qss/qheaderview/selectedFontWeight.qss
@@ -0,0 +1,16 @@
+QHeaderView::section {
+ background-color: red;
+ font-size: 10px;
+}
+
+QHeaderView::section:checked {
+ background-color: green;
+ font-size: 20px;
+ font-weight: bold;
+}
+
+QHeaderView::section:first {
+ background-color: yellow;
+ font-size: 20px;
+ font-weight: normal;
+}
diff --git a/tests/baseline/stylesheet/qss/qtreeview/showDecorationSelected.qss b/tests/baseline/stylesheet/qss/qtreeview/showDecorationSelected.qss
new file mode 100644
index 0000000000..b279b587bd
--- /dev/null
+++ b/tests/baseline/stylesheet/qss/qtreeview/showDecorationSelected.qss
@@ -0,0 +1,3 @@
+QTreeView {
+ show-decoration-selected: 1
+}
diff --git a/tests/baseline/stylesheet/qss/qtreeview/styledSelection.qss b/tests/baseline/stylesheet/qss/qtreeview/styledSelection.qss
new file mode 100644
index 0000000000..7d54a74fe5
--- /dev/null
+++ b/tests/baseline/stylesheet/qss/qtreeview/styledSelection.qss
@@ -0,0 +1,10 @@
+QTreeView {
+ alternate-background-color: yellow;
+ show-decoration-selected: 1;
+}
+QTreeView::item:selected:active {
+ background: qlineargradient(x1:0, y1:0 x2: 0, y2: 1, stop: 0 #fea1f1 stop: 1 #567dbc)
+}
+QTreeView::branch {
+ border: 2px
+}
diff --git a/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp b/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp
index 19bfed5e33..67a618988b 100644
--- a/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp
+++ b/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qbaselinetest.h>
#include <qwidgetbaselinetest.h>
@@ -27,6 +27,9 @@ private slots:
void tst_QTreeView_data();
void tst_QTreeView();
+ void tst_QHeaderView_data();
+ void tst_QHeaderView();
+
private:
QDir styleSheetDir;
};
@@ -63,7 +66,7 @@ void tst_Stylesheet::loadTestFiles()
for (const auto &qssFile : qssFiles) {
QFileInfo fileInfo(qssFile);
QFile file(qssFile);
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
QString styleSheet = QString::fromUtf8(file.readAll());
QBaselineTest::newRow(fileInfo.baseName().toUtf8()) << styleSheet;
}
@@ -160,19 +163,29 @@ void tst_Stylesheet::tst_QTreeView()
tw->header()->hide();
layout->addWidget(tw);
- for (int i = 0; i < 6; ++i) {
+ enum {
+ Unchecked = 0,
+ Checked = 1,
+ Children = 2,
+ Disabled = 3,
+ CheckedDisabled = 4,
+ ChildrenDisabled = 5,
+ NConfigs
+ };
+
+ for (int i = 0; i < NConfigs; ++i) {
QTreeWidgetItem *topLevelItem = new QTreeWidgetItem(tw, QStringList{QString("top %1").arg(i)});
switch (i) {
- case 0:
- case 3:
+ case Unchecked:
+ case Disabled:
topLevelItem->setCheckState(0, Qt::Unchecked);
break;
- case 1:
- case 4:
+ case Checked:
+ case CheckedDisabled:
topLevelItem->setCheckState(0, Qt::Checked);
break;
- case 2:
- case 5:
+ case Children:
+ case ChildrenDisabled:
topLevelItem->setCheckState(0, Qt::PartiallyChecked);
topLevelItem->setExpanded(true);
for (int j = 0; j < 2; ++j) {
@@ -181,7 +194,7 @@ void tst_Stylesheet::tst_QTreeView()
}
break;
}
- topLevelItem->setDisabled(i > 2);
+ topLevelItem->setDisabled(i >= Disabled);
}
testWindow()->setLayout(layout);
tw->setRootIsDecorated(true);
@@ -190,6 +203,25 @@ void tst_Stylesheet::tst_QTreeView()
QBASELINE_CHECK_DEFERRED(takeSnapshot(), "rootDecorated");
tw->setRootIsDecorated(false);
QBASELINE_CHECK_DEFERRED(takeSnapshot(), "rootNotDecorated");
+
+ tw->topLevelItem(Children)->child(0)->setSelected(true);
+ QBASELINE_CHECK_DEFERRED(takeSnapshot(), "itemSelected");
+}
+
+void tst_Stylesheet::tst_QHeaderView_data()
+{
+ loadTestFiles();
+}
+
+void tst_Stylesheet::tst_QHeaderView()
+{
+ QHBoxLayout *layout = new QHBoxLayout;
+ QTableWidget *tw = new QTableWidget(10, 10);
+ tw->setCurrentCell(1, 1);
+ layout->addWidget(tw);
+ testWindow()->setLayout(layout);
+ makeVisible();
+ QBASELINE_TEST(takeSnapshot());
}
#define main _realmain
@@ -198,7 +230,8 @@ QTEST_MAIN(tst_Stylesheet)
int main(int argc, char *argv[])
{
- qSetGlobalQHashSeed(0); // Avoid rendering variations caused by QHash randomization
+ // Avoid rendering variations caused by QHash randomization
+ QHashSeed::setDeterministicGlobalSeed();
QBaselineTest::handleCmdLineArgs(&argc, &argv);
return _realmain(argc, argv);
diff --git a/tests/baseline/text/CMakeLists.txt b/tests/baseline/text/CMakeLists.txt
index 707b3794b5..74d01337cb 100644
--- a/tests/baseline/text/CMakeLists.txt
+++ b/tests/baseline/text/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
list(APPEND test_data "./data")
qt_internal_add_test(tst_baseline_text
@@ -8,9 +11,10 @@ qt_internal_add_test(tst_baseline_text
tst_baseline_text.cpp
INCLUDE_DIRECTORIES
../shared
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
Qt::Network
TESTDATA ${test_data}
)
diff --git a/tests/baseline/text/data/colored_list.html b/tests/baseline/text/data/colored_list.html
new file mode 100644
index 0000000000..d1cca94460
--- /dev/null
+++ b/tests/baseline/text/data/colored_list.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html>
+<head>
+<style type="text/css">
+p, li { white-space: pre-wrap; }
+hr { height: 1px; border-width: 0; }
+li.unchecked::marker { content: "\2610"; }
+li.checked::marker { content: "\2612"; }
+body { background-color: #111155; color: #ffffff; }
+</style>
+</head>
+<body>
+
+<ul>
+<li>disc</li>
+<li style=" color:#a58d47;">bronze</li>
+<li style=" color:red;"><span style=" color:#ffcdb9;">red bullet, pink text</span></li>
+<li style=" color:#dddddd;" class="checked">checked</li>
+<li style=" color:#dddddd;" class="unchecked">unchecked</li>
+</ul>
+
+<ul type="circle">
+<li>circle</li>
+<li style=" color:#dddddd;">silver</li>
+<li style=" color:lightgrey;"><span style=" color:#ffcdb9;">grey bullet, pink text</span></li>
+<li style=" color:#dddddd;" class="checked">checked</li>
+<li style=" color:#dddddd;" class="unchecked">unchecked</li>
+</ul>
+
+<ul type="square">
+<li style=" color:#ffffff;">square</li>
+<li style=" color:#fceebb;">gold</li>
+<li style=" color:yellow;"><span style=" color:#ffcdb9;">yellow bullet, pink text</span></li>
+<li style=" color:#dddddd;" class="checked">checked</li>
+<li style=" color:#dddddd;" class="unchecked">unchecked</li>
+</ul>
+
+<ol>
+<li>decimal</li>
+<li style=" color:#a58d47;">bronze decimal</li>
+<li style=" color:red;"><span style=" color:#ffcdb9;">red number, pink text</span></li>
+</ol>
+
+<ol type="A">
+<li>uppercase</li>
+<li style=" color:#a58d47;">bronze uppercase</li>
+<li style=" color:red;"><span style=" color:#ffcdb9;">red letter, pink text</span></li>
+</ol>
+
+<ol type="a">
+<li>lowercase</li>
+<li style=" color:#a58d47;">bronze lowercase</li>
+<li style=" color:red;"><span style=" color:#ffcdb9;">red letter, pink text</span></li>
+</ol>
+
+<ol type="i">
+<li>lower roman</li>
+<li style=" color:#a58d47;">bronze roman</li>
+<li style=" color:red;"><span style=" color:#ffcdb9;">red number, pink text</span></li>
+</ol>
+
+<ol type="I">
+<li>upper roman</li>
+<li style=" color:#a58d47;">bronze roman</li>
+<li style=" color:red;"><span style=" color:#ffcdb9;">red number, pink text</span></li>
+</ol>
+</body>
+</html>
diff --git a/tests/baseline/text/tst_baseline_text.cpp b/tests/baseline/text/tst_baseline_text.cpp
index b3a0cf60fa..59a5f478a5 100644
--- a/tests/baseline/text/tst_baseline_text.cpp
+++ b/tests/baseline/text/tst_baseline_text.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qbaselinetest.h>
#include <qwidgetbaselinetest.h>
@@ -17,6 +17,7 @@ public:
private slots:
void tst_render_data();
void tst_render();
+ void tst_differentScriptsBackgrounds();
private:
QDir htmlDir;
@@ -48,7 +49,7 @@ void tst_Text::loadTestFiles()
for (const auto &htmlFile : htmlFiles) {
QFileInfo fileInfo(htmlFile);
QFile file(htmlFile);
- file.open(QFile::ReadOnly);
+ QVERIFY(file.open(QFile::ReadOnly));
QString html = QString::fromUtf8(file.readAll());
QBaselineTest::newRow(fileInfo.baseName().toUtf8()) << html;
}
@@ -81,6 +82,26 @@ void tst_Text::tst_render()
QBASELINE_TEST(image);
}
+void tst_Text::tst_differentScriptsBackgrounds()
+{
+ QTextDocument textDocument;
+ textDocument.setPageSize(QSizeF(800, 600));
+ textDocument.setHtml(QString::fromUtf8("<i><font style=\"font-size:72px\"><font style=\"background:#FFFF00\">イ雨エ</font></font></i>"));
+
+ QImage image(800, 600, QImage::Format_ARGB32);
+ image.fill(Qt::white);
+
+ {
+ QPainter painter(&image);
+
+ QAbstractTextDocumentLayout::PaintContext context;
+ context.palette.setColor(QPalette::Text, Qt::black);
+ textDocument.documentLayout()->draw(&painter, context);
+ }
+
+ QBASELINE_CHECK(image, "tst_differentScriptsBackgrounds");
+}
+
#define main _realmain
QTEST_MAIN(tst_Text)
@@ -88,7 +109,8 @@ QTEST_MAIN(tst_Text)
int main(int argc, char *argv[])
{
- qSetGlobalQHashSeed(0); // Avoid rendering variations caused by QHash randomization
+ // Avoid rendering variations caused by QHash randomization
+ QHashSeed::setDeterministicGlobalSeed();
QBaselineTest::handleCmdLineArgs(&argc, &argv);
return _realmain(argc, argv);
diff --git a/tests/baseline/widgets/CMakeLists.txt b/tests/baseline/widgets/CMakeLists.txt
index 124e67785f..07938f69b4 100644
--- a/tests/baseline/widgets/CMakeLists.txt
+++ b/tests/baseline/widgets/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
qt_internal_add_test(tst_baseline_widgets
SOURCES
../shared/baselineprotocol.cpp ../shared/baselineprotocol.h ../shared/lookup3.cpp
@@ -6,8 +9,9 @@ qt_internal_add_test(tst_baseline_widgets
tst_baseline_widgets.cpp
INCLUDE_DIRECTORIES
../shared
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
Qt::Network
)
diff --git a/tests/baseline/widgets/tst_baseline_widgets.cpp b/tests/baseline/widgets/tst_baseline_widgets.cpp
index 51803f0dec..8a763eb8fa 100644
--- a/tests/baseline/widgets/tst_baseline_widgets.cpp
+++ b/tests/baseline/widgets/tst_baseline_widgets.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qbaselinetest.h>
#include <qwidgetbaselinetest.h>
@@ -70,6 +70,18 @@ private slots:
void tst_QLineEdit_data();
void tst_QLineEdit();
+ void tst_QMenu_data();
+ void tst_QMenu();
+
+ void tst_QCombobox_data();
+ void tst_QCombobox();
+
+ void tst_QCommandLinkButton_data();
+ void tst_QCommandLinkButton();
+
+ void tst_QLCDNumber_data();
+ void tst_QLCDNumber();
+
private:
// Abstract SpinBox test for QSpinBox, QDoubleSpinBox, QDateTimeEdit, QDateEdit, QTimeEdit
@@ -945,19 +957,22 @@ void tst_Widgets::tst_QTreeView_data()
{
QTest::addColumn<bool>("showHeader");
QTest::addColumn<bool>("hasIcons");
+ QTest::addColumn<bool>("alternatingRowColors");
QTest::addColumn<QSize>("fixedSize");
QTest::addColumn<int>("treeHeight");
QTest::addColumn<int>("itemsPerNode");
// QSize() => variable size
- QTest::newRow("HeaderIcons_4_3") << true << true << QSize() << 3 << 2;
- QTest::newRow("NoHeaderNoIcons_4_4") << false << false << QSize(100, 350) << 3 << 2;
+ QTest::newRow("HeaderIcons_4_3") << true << true << false << QSize() << 3 << 2;
+ QTest::newRow("NoHeaderNoIcons_4_4") << false << false << false << QSize(100, 350) << 3 << 2;
+ QTest::newRow("AlternatingRows") << true << true << true << QSize() << 3 << 2;
}
void tst_Widgets::tst_QTreeView()
{
QFETCH(bool, showHeader);
QFETCH(bool, hasIcons);
+ QFETCH(bool, alternatingRowColors);
QFETCH(QSize, fixedSize);
QFETCH(int, treeHeight);
QFETCH(int, itemsPerNode);
@@ -971,6 +986,8 @@ void tst_Widgets::tst_QTreeView()
showHeader ? model.setHorizontalHeaderItem(0, new QStandardItem("TreeHeader"))
: treeView.setHeaderHidden(true);
+ treeView.setAlternatingRowColors(alternatingRowColors);
+
// Populate tree model
for (int i = 0; i < itemsPerNode; ++i) {
QStandardItem* root = tst_QTreeView_populateItem(treeHeight, i, hasIcons);
@@ -1085,17 +1102,187 @@ void tst_Widgets::tst_QLineEdit()
lineEdit.setAlignment(Qt::AlignCenter);
QBASELINE_CHECK_DEFERRED(takeSnapshot(), "alignedCenter");
- lineEdit.setSelection(0,text.length());
+ lineEdit.setSelection(0,text.size());
QBASELINE_CHECK_DEFERRED(takeSnapshot(), "textSelected");
}
+void tst_Widgets::tst_QMenu_data()
+{
+ QTest::addColumn<QStringList>("actions");
+
+ const QStringList menu1 = {"Text", "", "TextAndIcon", "", "SubMenu", "", "Checked"};
+ QTest::newRow("showMenuPopup") << menu1;
+}
+
+void tst_Widgets::tst_QMenu()
+{
+ QFETCH(const QStringList, actions);
+
+ testWindow()->resize(300, 200);
+
+ QBoxLayout layout(QBoxLayout::TopToBottom);
+ QMenu menu1;
+
+ for (const auto& menuItem : actions) {
+ if (!menuItem.isEmpty()) {
+ if (menuItem == "Text") {
+ menu1.addAction(QString("MenuItem"));
+ menu1.addAction(QString(""));
+ } else if (menuItem == "TextAndIcon") {
+ // Using pixmap icon
+ QPixmap pix(10, 10);
+ pix.fill(Qt::green);
+ menu1.addAction(QIcon(pix), QString("MenuWithIcon"));
+ menu1.addAction(QIcon(), QString("MenuNoIcon"));
+ } else if (menuItem == "SubMenu") {
+ QMenu* submenu = menu1.addMenu(QString("&Submenu1"));
+ submenu->addAction("SubMenuA");
+ submenu->addAction("SubMenuB");
+ } else if (menuItem == "Checked") {
+ auto checked = menu1.addAction(QString("MenuChecked"));
+ checked->setCheckable(true);
+ checked->setChecked(true);
+ auto notChecked = menu1.addAction(QString("MenuNotChecked"));
+ notChecked->setCheckable(true);
+ notChecked->setChecked(false);
+ }
+ } else {
+ menu1.addSeparator();
+ }
+ }
+
+ layout.addWidget(&menu1);
+ testWindow()->setLayout(&layout);
+
+ testWindow()->show();
+ QVERIFY(QTest::qWaitForWindowExposed(testWindow()));
+ QRect testWindowRect(testWindow()->geometry());
+ // There can be rounded corners in the window and this leads to test
+ // case to be fuzzy. Adjust window rectangle that need to be captured
+ int adjustPixel = menu1.geometry().left();
+ testWindowRect.adjust(adjustPixel, adjustPixel, -adjustPixel, -adjustPixel);
+ QBASELINE_CHECK_DEFERRED(takeScreenSnapshot(testWindowRect), "showitems");
+
+ // Normal menu item with text
+ QTest::keyClick(&menu1, Qt::Key_Down);
+ QBASELINE_CHECK_DEFERRED(takeScreenSnapshot(testWindowRect), "selectmenutext");
+ QTest::keyClick(&menu1, Qt::Key_Down);
+ QBASELINE_CHECK_DEFERRED(takeScreenSnapshot(testWindowRect), "selectmenunotext");
+
+ // Menu with icon and text
+ QTest::keyClick(&menu1, Qt::Key_Down);
+ QBASELINE_CHECK_DEFERRED(takeScreenSnapshot(testWindowRect), "selectmenuwithicon");
+ QTest::keyClick(&menu1, Qt::Key_Down);
+ QBASELINE_CHECK_DEFERRED(takeScreenSnapshot(testWindowRect), "selectmenuwithnullicon");
+
+ // Sub-menu items
+ QTest::keyClick(&menu1, Qt::Key_Down);
+ QTest::keyClick(&menu1, Qt::Key_Right);
+ QBASELINE_CHECK_DEFERRED(takeScreenSnapshot(testWindowRect), "selectsubmenu");
+ QTest::keyClick(&menu1, Qt::Key_Left);
+
+ // Checked menu
+ QTest::keyClick(&menu1, Qt::Key_Down);
+ QBASELINE_CHECK_DEFERRED(takeScreenSnapshot(testWindowRect), "selectmenuchecked");
+ QTest::keyClick(&menu1, Qt::Key_Down);
+ QBASELINE_CHECK_DEFERRED(takeScreenSnapshot(testWindowRect), "selectmenunotchecked");
+}
+
+void tst_Widgets::tst_QCombobox_data()
+{
+ QTest::addColumn<bool>("hasFrame");
+ QTest::addColumn<bool>("isEditable");
+
+ QTest::addRow("frameNonEditable") << true << false;
+ QTest::addRow("frameEditable") << true << true;
+ QTest::addRow("noFrameNonEditable") << false << false;
+ QTest::addRow("noFrameEditable") << false << true;
+}
+
+void tst_Widgets::tst_QCombobox()
+{
+ QFETCH(const bool, hasFrame);
+ QFETCH(const bool, isEditable);
+
+ testWindow()->resize(300, 300);
+
+ QScopedPointer<QComboBox> combobox(new QComboBox(testWindow()));
+ QStringList items;
+ items << tr("Item1") << tr("Item2") << tr("Item3");
+ QStringListModel* itemModel = new QStringListModel(items, this);
+ combobox->setModel(itemModel);
+ combobox->setFrame(hasFrame);
+ combobox->setEditable(isEditable);
+
+ QHBoxLayout layout;
+ layout.addWidget(combobox.get());
+ testWindow()->setLayout(&layout);
+ takeStandardSnapshots();
+
+ QTest::keyClick(combobox.get(), Qt::Key_Down, Qt::AltModifier);
+ QBASELINE_CHECK_DEFERRED(takeScreenSnapshot(testWindow()->geometry()), "combobox");
+}
+
+void tst_Widgets::tst_QCommandLinkButton_data()
+{
+ QTest::addColumn<bool>("flat");
+ QTest::addColumn<QString>("description");
+
+ QTest::addRow("flatDescription") << true << QString("Command button very specific to windows vista");
+ QTest::addRow("flatNoDescription") << true << QString("");
+ QTest::addRow("noFlatNoDescription") << false << QString("");
+}
+
+void tst_Widgets::tst_QCommandLinkButton()
+{
+ QFETCH(const bool, flat);
+ QFETCH(const QString, description);
+
+ QScopedPointer<QCommandLinkButton> commandLink(new QCommandLinkButton(QString("CommandLink"), description, testWindow()));
+ commandLink->setFlat(flat);
+ commandLink->setDescription(description);
+
+ QHBoxLayout layout;
+ layout.addWidget(commandLink.get());
+ testWindow()->setLayout(&layout);
+ takeStandardSnapshots();
+}
+
+void tst_Widgets::tst_QLCDNumber_data()
+{
+ QTest::addColumn<int>("segmentstyle");
+
+ QTest::addRow("outline") << 0;
+ QTest::addRow("filled") << 1;
+ QTest::addRow("flat") << 2;
+}
+
+void tst_Widgets::tst_QLCDNumber()
+{
+ QFETCH(const int, segmentstyle);
+
+ testWindow()->resize(100, 100);
+
+ QScopedPointer<QLCDNumber> lcdNumber(new QLCDNumber(99, testWindow()));
+ lcdNumber->setHexMode();
+ lcdNumber->setSegmentStyle(static_cast<QLCDNumber::SegmentStyle>(segmentstyle));
+
+
+ QHBoxLayout layout;
+ layout.addWidget(lcdNumber.get());
+ testWindow()->setLayout(&layout);
+
+ QBASELINE_CHECK_DEFERRED(takeSnapshot(), "lcdnumber");
+}
+
#define main _realmain
QTEST_MAIN(tst_Widgets)
#undef main
int main(int argc, char *argv[])
{
- qSetGlobalQHashSeed(0); // Avoid rendering variations caused by QHash randomization
+ // Avoid rendering variations caused by QHash randomization
+ QHashSeed::setDeterministicGlobalSeed();
QBaselineTest::handleCmdLineArgs(&argc, &argv);
return _realmain(argc, argv);