summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/linux/atspiadaptor.cpp44
-rw-r--r--src/gui/accessible/linux/qspi_struct_marshallers.cpp19
-rw-r--r--src/gui/accessible/linux/qspi_struct_marshallers_p.h16
-rw-r--r--src/gui/accessible/linux/qspimatchrulematcher.cpp2
-rw-r--r--src/gui/accessible/qaccessible_base.h4
-rw-r--r--src/gui/accessible/qaccessiblecache.cpp25
-rw-r--r--src/gui/doc/images/coordinatesystem-transformations.pngbin59180 -> 0 bytes
-rw-r--r--src/gui/doc/images/coordinatesystem-transformations.svg148
-rw-r--r--src/gui/doc/qtgui.qdocconf3
-rw-r--r--src/gui/doc/src/coordsys.qdoc2
-rw-r--r--src/gui/doc/src/external-resources.qdoc1
-rw-r--r--src/gui/image/qabstractfileiconprovider.cpp2
-rw-r--r--src/gui/itemmodels/qfileinfogatherer.cpp6
-rw-r--r--src/gui/kernel/qguiapplication.cpp6
-rw-r--r--src/gui/kernel/qguiapplication_p.h4
-rw-r--r--src/gui/kernel/qplatformintegrationfactory.cpp1
-rw-r--r--src/gui/kernel/qplatformthemefactory.cpp1
-rw-r--r--src/gui/kernel/qsurface.cpp5
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp51
-rw-r--r--src/gui/math3d/qmatrix4x4.h36
-rw-r--r--src/gui/math3d/qquaternion.cpp2
-rw-r--r--src/gui/math3d/qquaternion.h8
-rw-r--r--src/gui/math3d/qvectornd.cpp20
-rw-r--r--src/gui/opengl/platform/egl/qeglplatformcontext.cpp15
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp6
-rw-r--r--src/gui/painting/qdrawhelper.cpp4
-rw-r--r--src/gui/painting/qpagelayout.cpp8
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp7
-rw-r--r--src/gui/painting/qpainterpath.h2
-rw-r--r--src/gui/painting/qpdf.cpp1
-rw-r--r--src/gui/painting/qstroker.cpp6
-rw-r--r--src/gui/platform/unix/dbusmenu/qdbusplatformmenu.cpp1
-rw-r--r--src/gui/platform/unix/qxkbcommon.cpp6
-rw-r--r--src/gui/rhi/qrhimetal.mm22
-rw-r--r--src/gui/rhi/qrhivulkan.cpp181
-rw-r--r--src/gui/rhi/qrhivulkan_p.h16
-rw-r--r--src/gui/text/freetype/qfontengine_ft.cpp8
-rw-r--r--src/gui/text/freetype/qfontengine_ft_p.h4
-rw-r--r--src/gui/text/qcolrpaintgraphrenderer.cpp2
-rw-r--r--src/gui/text/qfont.cpp113
-rw-r--r--src/gui/text/qfont_p.h2
-rw-r--r--src/gui/text/qfontengine.cpp7
-rw-r--r--src/gui/text/qrawfont.cpp2
-rw-r--r--src/gui/text/qrawfont.h2
-rw-r--r--src/gui/text/qtextdocument.cpp7
-rw-r--r--src/gui/text/qtextdocument_p.cpp1
-rw-r--r--src/gui/text/qtextengine.cpp6
-rw-r--r--src/gui/text/qtextengine_p.h2
-rw-r--r--src/gui/text/qtexttable.cpp4
-rw-r--r--src/gui/text/windows/qwindowsfontdatabase.cpp4
-rw-r--r--src/gui/text/windows/qwindowsfontdatabase_p.h4
-rw-r--r--src/gui/text/windows/qwindowsfontdatabasebase.cpp6
-rw-r--r--src/gui/text/windows/qwindowsfontenginedirectwrite.cpp2
-rw-r--r--src/gui/util/qlayoutpolicy.cpp5
54 files changed, 657 insertions, 205 deletions
diff --git a/src/gui/accessible/linux/atspiadaptor.cpp b/src/gui/accessible/linux/atspiadaptor.cpp
index dad0ac2b74a..dae83437b89 100644
--- a/src/gui/accessible/linux/atspiadaptor.cpp
+++ b/src/gui/accessible/linux/atspiadaptor.cpp
@@ -132,7 +132,7 @@ AtSpiAdaptor::~AtSpiAdaptor()
*/
QString AtSpiAdaptor::introspect(const QString &path) const
{
- static const QLatin1StringView accessibleIntrospection(
+ constexpr auto accessibleIntrospection =
" <interface name=\"org.a11y.atspi.Accessible\">\n"
" <property access=\"read\" type=\"s\" name=\"Name\"/>\n"
" <property access=\"read\" type=\"s\" name=\"Description\"/>\n"
@@ -182,9 +182,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"s\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView actionIntrospection(
+ constexpr auto actionIntrospection =
" <interface name=\"org.a11y.atspi.Action\">\n"
" <property access=\"read\" type=\"i\" name=\"NActions\"/>\n"
" <method name=\"GetDescription\">\n"
@@ -208,9 +208,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView applicationIntrospection(
+ constexpr auto applicationIntrospection =
" <interface name=\"org.a11y.atspi.Application\">\n"
" <property access=\"read\" type=\"s\" name=\"ToolkitName\"/>\n"
" <property access=\"read\" type=\"s\" name=\"Version\"/>\n"
@@ -223,9 +223,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"s\" name=\"address\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView collectionIntrospection(
+ constexpr auto collectionIntrospection =
" <interface name=\"org.a11y.atspi.Collection\">\n"
" <method name=\"GetMatches\">\n"
" <arg direction=\"in\" name=\"rule\" type=\"(aiia{ss}iaiiasib)\"/>\n"
@@ -266,9 +266,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QSpiReferenceSet\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView componentIntrospection(
+ constexpr auto componentIntrospection =
" <interface name=\"org.a11y.atspi.Component\">\n"
" <method name=\"Contains\">\n"
" <arg direction=\"in\" type=\"i\" name=\"x\"/>\n"
@@ -329,9 +329,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView editableTextIntrospection(
+ constexpr auto editableTextIntrospection =
" <interface name=\"org.a11y.atspi.EditableText\">\n"
" <method name=\"SetTextContents\">\n"
" <arg direction=\"in\" type=\"s\" name=\"newContents\"/>\n"
@@ -362,9 +362,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView selectionIntrospection(
+ constexpr auto selectionIntrospection =
" <interface name=\"org.a11y.atspi.Selection\">\n"
" <property name=\"NSelectedChildren\" type=\"i\" access=\"read\"/>\n"
" <method name=\"GetSelectedChild\">\n"
@@ -395,9 +395,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView tableIntrospection(
+ constexpr auto tableIntrospection =
" <interface name=\"org.a11y.atspi.Table\">\n"
" <property access=\"read\" type=\"i\" name=\"NRows\"/>\n"
" <property access=\"read\" type=\"i\" name=\"NColumns\"/>\n"
@@ -503,9 +503,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\" name=\"is_selected\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView tableCellIntrospection(
+ constexpr auto tableCellIntrospection =
" <interface name=\"org.a11y.atspi.TableCell\">\n"
" <property access=\"read\" name=\"ColumnSpan\" type=\"i\" />\n"
" <property access=\"read\" name=\"Position\" type=\"(ii)\">\n"
@@ -531,9 +531,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <annotation value=\"QSpiObjectReferenceArray\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView textIntrospection(
+ constexpr auto textIntrospection =
" <interface name=\"org.a11y.atspi.Text\">\n"
" <property access=\"read\" type=\"i\" name=\"CharacterCount\"/>\n"
" <property access=\"read\" type=\"i\" name=\"CaretOffset\"/>\n"
@@ -670,9 +670,9 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
- static const QLatin1StringView valueIntrospection(
+ constexpr auto valueIntrospection =
" <interface name=\"org.a11y.atspi.Value\">\n"
" <property access=\"read\" type=\"d\" name=\"MinimumValue\"/>\n"
" <property access=\"read\" type=\"d\" name=\"MaximumValue\"/>\n"
@@ -682,7 +682,7 @@ QString AtSpiAdaptor::introspect(const QString &path) const
" <arg direction=\"in\" type=\"d\" name=\"value\"/>\n"
" </method>\n"
" </interface>\n"
- );
+ ""_L1;
QAccessibleInterface * interface = interfaceFromPath(path);
if (!interface) {
diff --git a/src/gui/accessible/linux/qspi_struct_marshallers.cpp b/src/gui/accessible/linux/qspi_struct_marshallers.cpp
index 241bad502e3..5e171244cd0 100644
--- a/src/gui/accessible/linux/qspi_struct_marshallers.cpp
+++ b/src/gui/accessible/linux/qspi_struct_marshallers.cpp
@@ -28,7 +28,6 @@ QT_IMPL_METATYPE_EXTERN(QSpiRelationArray)
QT_IMPL_METATYPE_EXTERN(QSpiTextRange)
QT_IMPL_METATYPE_EXTERN(QSpiTextRangeList)
QT_IMPL_METATYPE_EXTERN(QSpiAttributeSet)
-QT_IMPL_METATYPE_EXTERN(QSpiAppUpdate)
QT_IMPL_METATYPE_EXTERN(QSpiDeviceEvent)
QT_IMPL_METATYPE_EXTERN(QSpiMatchRule)
@@ -134,23 +133,6 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiEventListener
return argument;
}
-/* QSpiAppUpdate */
-/*---------------------------------------------------------------------------*/
-
-QDBusArgument &operator<<(QDBusArgument &argument, const QSpiAppUpdate &update) {
- argument.beginStructure();
- argument << update.type << update.address;
- argument.endStructure();
- return argument;
-}
-
-const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiAppUpdate &update) {
- argument.beginStructure();
- argument >> update.type >> update.address;
- argument.endStructure();
- return argument;
-}
-
/* QSpiRelationArrayEntry */
/*---------------------------------------------------------------------------*/
@@ -245,7 +227,6 @@ void qSpiInitializeStructTypes()
qDBusRegisterMetaType<QSpiEventListenerArray>();
qDBusRegisterMetaType<QSpiDeviceEvent>();
qDBusRegisterMetaType<QSpiMatchRule>();
- qDBusRegisterMetaType<QSpiAppUpdate>();
qDBusRegisterMetaType<QSpiRelationArrayEntry>();
qDBusRegisterMetaType<QSpiRelationArray>();
}
diff --git a/src/gui/accessible/linux/qspi_struct_marshallers_p.h b/src/gui/accessible/linux/qspi_struct_marshallers_p.h
index fe2d52fb4c2..4c446a97040 100644
--- a/src/gui/accessible/linux/qspi_struct_marshallers_p.h
+++ b/src/gui/accessible/linux/qspi_struct_marshallers_p.h
@@ -106,21 +106,6 @@ Q_DECLARE_TYPEINFO(QSpiTextRange, Q_RELOCATABLE_TYPE);
typedef QList<QSpiTextRange> QSpiTextRangeList;
typedef QMap <QString, QString> QSpiAttributeSet;
-enum QSpiAppUpdateType {
- QSPI_APP_UPDATE_ADDED = 0,
- QSPI_APP_UPDATE_REMOVED = 1
-};
-Q_DECLARE_TYPEINFO(QSpiAppUpdateType, Q_PRIMITIVE_TYPE);
-
-struct QSpiAppUpdate {
- int type; /* Is an application added or removed */
- QString address; /* D-Bus address of application added or removed */
-};
-Q_DECLARE_TYPEINFO(QSpiAppUpdate, Q_RELOCATABLE_TYPE);
-
-QDBusArgument &operator<<(QDBusArgument &argument, const QSpiAppUpdate &update);
-const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiAppUpdate &update);
-
struct QSpiDeviceEvent {
unsigned int type;
int id;
@@ -171,7 +156,6 @@ QT_DECL_METATYPE_EXTERN(QSpiRelationArray, /* not exported */)
QT_DECL_METATYPE_EXTERN(QSpiTextRange, /* not exported */)
QT_DECL_METATYPE_EXTERN(QSpiTextRangeList, /* not exported */)
QT_DECL_METATYPE_EXTERN(QSpiAttributeSet, /* not exported */)
-QT_DECL_METATYPE_EXTERN(QSpiAppUpdate, /* not exported */)
QT_DECL_METATYPE_EXTERN(QSpiDeviceEvent, /* not exported */)
QT_DECL_METATYPE_EXTERN(QSpiMatchRule, /* not exported */)
diff --git a/src/gui/accessible/linux/qspimatchrulematcher.cpp b/src/gui/accessible/linux/qspimatchrulematcher.cpp
index 48357f7ae63..a63bdd04443 100644
--- a/src/gui/accessible/linux/qspimatchrulematcher.cpp
+++ b/src/gui/accessible/linux/qspimatchrulematcher.cpp
@@ -37,7 +37,7 @@ QSpiMatchRuleMatcher::QSpiMatchRuleMatcher(const QSpiMatchRule &matchRule)
}
}
- // use qualified interface names to match what accessibleInterfaces() returns
+ // use qualified interface names to match what AtSpiAdaptor::accessibleInterfaces returns
m_interfaces.reserve(matchRule.interfaces.size());
for (const QString &ifaceName : matchRule.interfaces)
m_interfaces.push_back("org.a11y.atspi."_L1 + ifaceName);
diff --git a/src/gui/accessible/qaccessible_base.h b/src/gui/accessible/qaccessible_base.h
index 3881c6346a0..04efeddf06f 100644
--- a/src/gui/accessible/qaccessible_base.h
+++ b/src/gui/accessible/qaccessible_base.h
@@ -175,11 +175,15 @@ public:
// quint64 alertMedium : 1;
// quint64 alertHigh : 1;
+ Q_DECL_UNUSED_MEMBER quint64 qt_reserved : 27;
+
State() {
std::memset(this, 0, sizeof(State));
}
friend inline bool operator==(const QAccessible::State &first, const QAccessible::State &second)
{
+ static_assert(std::has_unique_object_representations_v<State>,
+ "memcmp() cannot be used on types with padding");
return std::memcmp(&first, &second, sizeof(QAccessible::State)) == 0;
}
};
diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp
index a8255e04c02..b5dcdca6270 100644
--- a/src/gui/accessible/qaccessiblecache.cpp
+++ b/src/gui/accessible/qaccessiblecache.cpp
@@ -4,6 +4,7 @@
#include "qaccessiblecache_p.h"
#include <QtCore/qdebug.h>
#include <QtCore/qloggingcategory.h>
+#include <private/qguiapplication_p.h>
#if QT_CONFIG(accessibility)
@@ -18,6 +19,7 @@ Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCache, "qt.accessibility.cache");
*/
static QAccessibleCache *accessibleCache = nullptr;
+static bool inCacheDestructor = false;
static void cleanupAccessibleCache()
{
@@ -31,6 +33,8 @@ QAccessibleObjectDestroyedEvent::~QAccessibleObjectDestroyedEvent()
QAccessibleCache::~QAccessibleCache()
{
+ inCacheDestructor = true;
+
for (QAccessible::Id id: idToInterface.keys())
deleteInterface(id);
}
@@ -176,10 +180,27 @@ void QAccessibleCache::sendObjectDestroyedEvent(QObject *obj)
void QAccessibleCache::deleteInterface(QAccessible::Id id, QObject *obj)
{
- QAccessibleInterface *iface = idToInterface.take(id);
+ const auto it = idToInterface.find(id);
+ if (it == idToInterface.end()) // the interface may be deleted already
+ return;
+
+ QAccessibleInterface *iface = *it;
qCDebug(lcAccessibilityCache) << "delete - id:" << id << " iface:" << iface;
- if (!iface) // the interface may be deleted already
+ if (!iface) {
+ idToInterface.erase(it);
return;
+ }
+
+ // QObjects send this from their destructors, but the interfaces
+ // with no associated object call deleteInterface directly.
+ if (!inCacheDestructor && !obj && !iface->object()) {
+ if (QGuiApplicationPrivate::is_app_running && !QGuiApplicationPrivate::is_app_closing && QAccessible::isActive()) {
+ QAccessibleObjectDestroyedEvent event(id);
+ QAccessible::updateAccessibility(&event);
+ }
+ }
+
+ idToInterface.erase(it);
interfaceToId.take(iface);
if (!obj)
obj = iface->object();
diff --git a/src/gui/doc/images/coordinatesystem-transformations.png b/src/gui/doc/images/coordinatesystem-transformations.png
deleted file mode 100644
index 2736213c072..00000000000
--- a/src/gui/doc/images/coordinatesystem-transformations.png
+++ /dev/null
Binary files differ
diff --git a/src/gui/doc/images/coordinatesystem-transformations.svg b/src/gui/doc/images/coordinatesystem-transformations.svg
new file mode 100644
index 00000000000..a3bc17af3ef
--- /dev/null
+++ b/src/gui/doc/images/coordinatesystem-transformations.svg
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="760" height="300"
+ viewBox="0 0 760 300"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.2" baseProfile="tiny">
+
+<style>
+ svg .line-style { stroke: black; fill: none; stroke-width: 2 }
+ svg .text-style { font: 14px arial; fill: black }
+ svg .mono-text-style { font: 14px monospace; fill: black }
+ svg .heading-style { font: 14px arial; fill: black; font-weight: bold }
+ svg .shape-style { stroke: none; fill: black }
+ svg .dash-style { stroke-dasharray: 4,3; stroke-dashoffset: 0; fill: none;
+ stroke: black }
+
+ svg .window-line-style { stroke: red; fill: none; stroke-width: 2 }
+ svg .window-text-style { font: 14px arial; fill: red }
+ svg .window-shape-style { stroke: none; fill: red }
+ svg .window-dash-style { stroke-dasharray: 4,3; stroke-dashoffset: 0; fill: none;
+ stroke: red }
+
+ svg.dark .line-style { stroke: #f2f2f2; fill: none; stroke-width: 2 }
+ svg.dark .text-style { font: 14px arial; fill: #f2f2f2 }
+ svg.dark .mono-text-style { font: 14px monospace; fill: #f2f2f2 }
+ svg.dark .heading-style { font: 14px arial; fill: #f2f2f2; font-weight: bold }
+ svg.dark .shape-style { stroke: none; fill: #f2f2f2 }
+ svg.dark .dash-style { stroke-dasharray: 4,3; stroke-dashoffset: 0; fill: none;
+ stroke: #f2f2f2 }
+ svg.dark .window-line-style { stroke: yellow; fill: none; stroke-width: 2 }
+ svg.dark .window-text-style { font: 14px arial; fill: yellow }
+ svg.dark .window-shape-style { stroke: none; fill: yellow }
+ svg.dark .window-dash-style { stroke-dasharray: 4,3; stroke-dashoffset: 0; fill: none;
+ stroke: yellow }
+
+ [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none; stroke-width: 2 }
+ [data-theme="dark"] svg .text-style { font: 14px arial; fill: #f2f2f2 }
+ [data-theme="dark"] svg .mono-text-style { font: 14px monospace; fill: #f2f2f2 }
+ [data-theme="dark"] svg .heading-style { font: 14px arial; fill: #f2f2f2; font-weight: bold }
+ [data-theme="dark"] svg .shape-style { stroke: none; fill: #f2f2f2 }
+ [data-theme="dark"] svg .dash-style { stroke-dasharray: 4,3; stroke-dashoffset: 0; fill: none;
+ stroke: #f2f2f2 }
+ [data-theme="dark"] svg .window-line-style { stroke: yellow; fill: none; stroke-width: 2 }
+ [data-theme="dark"] svg .window-text-style { font: 14px arial; fill: yellow }
+ [data-theme="dark"] svg .window-shape-style { stroke: none; fill: yellow }
+ [data-theme="dark"] svg .window-dash-style { stroke-dasharray: 4,3; stroke-dashoffset: 0; fill: none;
+ stroke: yellow }
+
+ [data-theme="light"] svg .line-style { stroke: black; fill: none; stroke-width: 2 }
+ [data-theme="light"] svg .text-style { font: 14px arial; fill: black }
+ [data-theme="light"] svg .mono-text-style { font: 14px monospace; fill: black }
+ [data-theme="light"] svg .heading-style { font: 14px arial; fill: black; font-weight: bold }
+ [data-theme="light"] svg .shape-style { stroke: none; fill: black }
+ [data-theme="light"] svg .dash-style { stroke-dasharray: 4,3; stroke-dashoffset: 0; fill: none;
+ stroke: black }
+ [data-theme="light"] svg .window-line-style { stroke: red; fill: none; stroke-width: 2 }
+ [data-theme="light"] svg .window-text-style { font: 14px arial; fill: red }
+ [data-theme="light"] svg .window-shape-style { stroke: none; fill: red }
+ [data-theme="light"] svg .window-dash-style { stroke-dasharray: 4,3; stroke-dashoffset: 0; fill: none;
+ stroke: red }
+</style>
+
+<text x="50" y="20" fill="black" font-size="14px" font-family="arial"
+ font-weight="bold"
+ class="heading-style">World coordinates</text>
+
+<g transform="translate(20, 30)">
+ <rect x="0" y="0" width="200" height="200" stroke="black" fill="none" stroke-dasharray="4,3" stroke-dashoffset="0"
+ class="dash-style" />
+
+ <path d="M5,5 L16,10 L10,16 L5,5" class="shape-style" />
+ <polyline points="5,5 20,20" stroke="black" stroke-width="2" fill="none" class="line-style" />
+ <text x="25" y="30" fill="black" font-size="14px" font-family="arial"
+ class="text-style">(0, 0)</text>
+
+ <path d="M195,195 L184,190 L190,184 L195,195" class="shape-style" />
+ <polyline points="195,195 180,180" stroke="black" stroke-width="2" fill="none" class="line-style" />
+ <text x="115" y="175" fill="black" font-size="14px" font-family="arial"
+ class="text-style">(100, 100)</text>
+
+ <polyline points="-3,-3 3,3" stroke="black" stroke-width="2" class="line-style" />
+ <polyline points="-3,3 3,-3" stroke="black" stroke-width="2" class="line-style" />
+</g>
+
+<g transform="translate(45,235)">
+ <path d="M 0,0 c 0,25 10,35 25,35" stroke="black" stroke-width="2" fill="none" class="line-style" />
+ <path d="M 25,30 l 10,5 l -10,5 z" class="shape-style" />
+ <text x="40" y="40" fill="black" font-size="14px" font-family="monospace"
+ class="mono-text-style">setWindow(-50, -50, 100, 100)</text>
+ <path d="M 290,35 c 15,0 25,-10 25,-35" stroke="black" stroke-width="2" fill="none" class="line-style" />
+ <path d="M 315,0 l 5,10 l -10,0 z" class="shape-style" />
+</g>
+
+<text x="300" y="20" fill="black" font-size="14px" font-family="arial"
+ font-weight="bold"
+ class="heading-style">"Window" coordinates</text>
+
+<g transform="translate(280, 30)">
+
+ <rect x="0" y="0" width="200" height="200" stroke="red" fill="none" stroke-dasharray="4,3" stroke-dashoffset="0"
+ class="window-dash-style" />
+
+ <path d="M5,5 L16,10 L10,16 L5,5" fill="red" class="window-shape-style" />
+ <polyline points="5,5 20,20" stroke="red" stroke-width="2" fill="none" class="window-line-style" />
+ <text x="25" y="30" fill="red" font-size="14px" font-family="arial"
+ class="window-text-style">(-50, -50)</text>
+
+ <path d="M195,195 L184,190 L190,184 L195,195" fill="red" class="window-shape-style" />
+ <polyline points="195,195 180,180" stroke="red" stroke-width="2" fill="none" class="window-line-style" />
+ <text x="130" y="175" fill="red" font-size="14px" font-family="arial"
+ class="window-text-style">(50, 50)</text>
+
+ <polyline points="97,97 103,103" stroke="red" stroke-width="2" class="window-line-style" />
+ <polyline points="97,103 103,97" stroke="red" stroke-width="2" class="window-line-style" />
+</g>
+
+<g transform="translate(395,235)">
+ <path d="M 0,0 c 0,25 10,35 25,35" stroke="black" stroke-width="2" fill="none" class="line-style" />
+ <path d="M 25,30 l 10,5 l -10,5 z" class="shape-style" />
+ <text x="40" y="40" fill="black" font-size="14px" font-family="monospace"
+ class="mono-text-style">setViewport(45, 25, 50, 50)</text>
+ <path d="M 270,35 c 15,0 25,-10 25,-35" stroke="black" stroke-width="2" fill="none" class="line-style" />
+ <path d="M 295,0 l 5,10 l -10,0 z" class="shape-style" />
+</g>
+
+<text x="570" y="20" fill="black" font-size="14px" font-family="arial"
+ font-weight="bold"
+ class="heading-style">Device coordinates</text>
+
+<g transform="translate(540, 30)">
+
+ <rect x="0" y="0" width="200" height="200" stroke="black" stroke-width="2" fill="none" class="line-style" />
+
+ <path d="M5,5 L16,10 L10,16 L5,5" class="shape-style" />
+ <polyline points="5,5 20,20" stroke="black" stroke-width="2" fill="none" class="line-style" />
+ <text x="25" y="30" fill="black" font-size="14px" font-family="arial"
+ class="text-style">(0, 0)</text>
+
+ <path d="M195,195 L184,190 L190,184 L195,195" class="shape-style" />
+ <polyline points="195,195 180,180" stroke="black" stroke-width="2" fill="none" class="line-style" />
+ <text x="115" y="175" fill="black" font-size="14px" font-family="arial"
+ class="text-style">(100, 100)</text>
+
+ <rect x="90" y="50" width="100" height="100" stroke="red" fill="none" stroke-dasharray="4,3" stroke-dashoffset="0"
+ class="window-dash-style" />
+ <polyline points="137,97 143,103" stroke="red" stroke-width="2" class="window-line-style" />
+ <polyline points="137,103 143,97" stroke="red" stroke-width="2" class="window-line-style" />
+</g>
+
+</svg>
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index 24d9d522735..8b7569c1296 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -50,7 +50,8 @@ depends += \
qtshadertools \
qttestlib \
qtplatformintegration \
- qthelp
+ qthelp \
+ qtquickcontrols
headerdirs += ..
diff --git a/src/gui/doc/src/coordsys.qdoc b/src/gui/doc/src/coordsys.qdoc
index 3dd064c19bc..22e14121af6 100644
--- a/src/gui/doc/src/coordsys.qdoc
+++ b/src/gui/doc/src/coordsys.qdoc
@@ -321,7 +321,7 @@
still transformed to the viewport using the same linear algebraic
approach.
- \image coordinatesystem-transformations.png {Illustration showing
+ \image coordinatesystem-transformations.svg {Illustration showing
how coordinates are mapped using viewport, "window" and
transformation matrix}
diff --git a/src/gui/doc/src/external-resources.qdoc b/src/gui/doc/src/external-resources.qdoc
index 0f356dd5046..14ed0817e62 100644
--- a/src/gui/doc/src/external-resources.qdoc
+++ b/src/gui/doc/src/external-resources.qdoc
@@ -36,6 +36,7 @@
\externalpage https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
\title Freedesktop Icon Naming Specification
*/
+
/*!
\externalpage https://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html#directory_layout
\title Icon Theme Specification - Directory Layout
diff --git a/src/gui/image/qabstractfileiconprovider.cpp b/src/gui/image/qabstractfileiconprovider.cpp
index 78777ec115a..ad646a6b89a 100644
--- a/src/gui/image/qabstractfileiconprovider.cpp
+++ b/src/gui/image/qabstractfileiconprovider.cpp
@@ -288,3 +288,5 @@ QString QAbstractFileIconProvider::type(const QFileInfo &info) const
}
QT_END_NAMESPACE
+
+#include "moc_qabstractfileiconprovider.cpp"
diff --git a/src/gui/itemmodels/qfileinfogatherer.cpp b/src/gui/itemmodels/qfileinfogatherer.cpp
index b7ab3dbbc46..ea19db0d20f 100644
--- a/src/gui/itemmodels/qfileinfogatherer.cpp
+++ b/src/gui/itemmodels/qfileinfogatherer.cpp
@@ -46,6 +46,12 @@ static QString translateDriveName(const QFileInfo &drive)
}
/*!
+ \class QFileInfoGatherer
+ \inmodule QtGui
+ \internal
+*/
+
+/*!
Creates thread
*/
QFileInfoGatherer::QFileInfoGatherer(QObject *parent)
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 741b089306e..e8df40f21b2 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -490,6 +490,12 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
*/
/*!
+ \class QGuiApplicationPrivate
+ \inmodule QtGui
+ \internal
+*/
+
+/*!
Initializes the window system and constructs an application object with
\a argc command line arguments in \a argv.
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index cb4702b5f7e..633ae7895ba 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -228,8 +228,8 @@ public:
// to use single-point precision.
friend constexpr bool operator==(const QLastCursorPosition &p1, const QPointF &p2) noexcept
{
- return qFuzzyCompare(float(p1.x()), float(p2.x()))
- && qFuzzyCompare(float(p1.y()), float(p2.y()));
+ return QtPrivate::fuzzyCompare(float(p1.x()), float(p2.x()))
+ && QtPrivate::fuzzyCompare(float(p1.y()), float(p2.y()));
}
friend constexpr bool operator!=(const QLastCursorPosition &p1, const QPointF &p2) noexcept
{
diff --git a/src/gui/kernel/qplatformintegrationfactory.cpp b/src/gui/kernel/qplatformintegrationfactory.cpp
index d0a5e8871f8..d113e86090d 100644
--- a/src/gui/kernel/qplatformintegrationfactory.cpp
+++ b/src/gui/kernel/qplatformintegrationfactory.cpp
@@ -24,6 +24,7 @@ QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platfor
}
/*!
+ \internal
Returns the list of valid keys, i.e. the keys this factory can
create styles for.
diff --git a/src/gui/kernel/qplatformthemefactory.cpp b/src/gui/kernel/qplatformthemefactory.cpp
index beefa1c2942..3ac462598fd 100644
--- a/src/gui/kernel/qplatformthemefactory.cpp
+++ b/src/gui/kernel/qplatformthemefactory.cpp
@@ -31,6 +31,7 @@ QPlatformTheme *QPlatformThemeFactory::create(const QString& key, const QString
}
/*!
+ \internal
Returns the list of valid keys, i.e. the keys this factory can
create styles for.
diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp
index e2bafa73988..f361ec86c2d 100644
--- a/src/gui/kernel/qsurface.cpp
+++ b/src/gui/kernel/qsurface.cpp
@@ -68,7 +68,10 @@ QT_IMPL_METATYPE_EXTERN_TAGGED(QSurface*, QSurface_ptr)
bool QSurface::supportsOpenGL() const
{
- return surfaceType() == OpenGLSurface;
+ static bool openGLOnRasterSurfaceSupported =
+ QGuiApplicationPrivate::instance()->platformIntegration()->hasCapability(QPlatformIntegration::OpenGLOnRasterSurface);
+ return surfaceType() == OpenGLSurface
+ || (surfaceType() == RasterSurface && openGLOnRasterSurfaceSupported);
}
/*!
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index f6a06fd47ca..ec6e696ba00 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -294,6 +294,7 @@ double QMatrix4x4::determinant() const
if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity)
return 1.0;
+ Q_DECL_UNINITIALIZED
double mm[4][4];
copyToDoubles(m, mm);
if (flagBits < Rotation2D)
@@ -355,8 +356,10 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const
*invertible = true;
return orthonormalInverse();
} else if (flagBits < Perspective) {
+ Q_DECL_UNINITIALIZED
QMatrix4x4 inv(Qt::Uninitialized);
+ Q_DECL_UNINITIALIZED
double mm[4][4];
copyToDoubles(m, mm);
@@ -391,8 +394,10 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const
return inv;
}
+ Q_DECL_UNINITIALIZED
QMatrix4x4 inv(Qt::Uninitialized);
+ Q_DECL_UNINITIALIZED
double mm[4][4];
copyToDoubles(m, mm);
@@ -465,6 +470,7 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const
return inv;
}
+ Q_DECL_UNINITIALIZED
double mm[4][4];
copyToDoubles(m, mm);
double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2);
@@ -493,6 +499,7 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const
*/
QMatrix4x4 QMatrix4x4::transposed() const
{
+ Q_DECL_UNINITIALIZED
QMatrix4x4 result(Qt::Uninitialized);
for (int row = 0; row < 4; ++row) {
for (int col = 0; col < 4; ++col) {
@@ -709,6 +716,7 @@ QMatrix4x4& QMatrix4x4::operator/=(float divisor)
*/
QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor)
{
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = matrix.m[0][0] / divisor;
m.m[0][1] = matrix.m[0][1] / divisor;
@@ -738,22 +746,22 @@ QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor)
*/
bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2) noexcept
{
- return qFuzzyCompare(m1.m[0][0], m2.m[0][0]) &&
- qFuzzyCompare(m1.m[0][1], m2.m[0][1]) &&
- qFuzzyCompare(m1.m[0][2], m2.m[0][2]) &&
- qFuzzyCompare(m1.m[0][3], m2.m[0][3]) &&
- qFuzzyCompare(m1.m[1][0], m2.m[1][0]) &&
- qFuzzyCompare(m1.m[1][1], m2.m[1][1]) &&
- qFuzzyCompare(m1.m[1][2], m2.m[1][2]) &&
- qFuzzyCompare(m1.m[1][3], m2.m[1][3]) &&
- qFuzzyCompare(m1.m[2][0], m2.m[2][0]) &&
- qFuzzyCompare(m1.m[2][1], m2.m[2][1]) &&
- qFuzzyCompare(m1.m[2][2], m2.m[2][2]) &&
- qFuzzyCompare(m1.m[2][3], m2.m[2][3]) &&
- qFuzzyCompare(m1.m[3][0], m2.m[3][0]) &&
- qFuzzyCompare(m1.m[3][1], m2.m[3][1]) &&
- qFuzzyCompare(m1.m[3][2], m2.m[3][2]) &&
- qFuzzyCompare(m1.m[3][3], m2.m[3][3]);
+ return QtPrivate::fuzzyCompare(m1.m[0][0], m2.m[0][0])
+ && QtPrivate::fuzzyCompare(m1.m[0][1], m2.m[0][1])
+ && QtPrivate::fuzzyCompare(m1.m[0][2], m2.m[0][2])
+ && QtPrivate::fuzzyCompare(m1.m[0][3], m2.m[0][3])
+ && QtPrivate::fuzzyCompare(m1.m[1][0], m2.m[1][0])
+ && QtPrivate::fuzzyCompare(m1.m[1][1], m2.m[1][1])
+ && QtPrivate::fuzzyCompare(m1.m[1][2], m2.m[1][2])
+ && QtPrivate::fuzzyCompare(m1.m[1][3], m2.m[1][3])
+ && QtPrivate::fuzzyCompare(m1.m[2][0], m2.m[2][0])
+ && QtPrivate::fuzzyCompare(m1.m[2][1], m2.m[2][1])
+ && QtPrivate::fuzzyCompare(m1.m[2][2], m2.m[2][2])
+ && QtPrivate::fuzzyCompare(m1.m[2][3], m2.m[2][3])
+ && QtPrivate::fuzzyCompare(m1.m[3][0], m2.m[3][0])
+ && QtPrivate::fuzzyCompare(m1.m[3][1], m2.m[3][1])
+ && QtPrivate::fuzzyCompare(m1.m[3][2], m2.m[3][2])
+ && QtPrivate::fuzzyCompare(m1.m[3][3], m2.m[3][3]);
}
@@ -1141,6 +1149,7 @@ void QMatrix4x4::rotate(float angle, float x, float y, float z)
z = float(double(z) / len);
}
float ic = 1.0f - c;
+ Q_DECL_UNINITIALIZED
QMatrix4x4 rot(Qt::Uninitialized);
rot.m[0][0] = x * x * ic + c;
rot.m[1][0] = x * y * ic - z * s;
@@ -1244,6 +1253,7 @@ void QMatrix4x4::projectedRotate(float angle, float x, float y, float z, float d
z = float(double(z) / len);
}
const float ic = 1.0f - c;
+ Q_DECL_UNINITIALIZED
QMatrix4x4 rot(Qt::Uninitialized);
rot.m[0][0] = x * x * ic + c;
rot.m[1][0] = x * y * ic - z * s;
@@ -1306,6 +1316,7 @@ void QMatrix4x4::rotate(const QQuaternion& quaternion)
// Algorithm from:
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
const float f2x = quaternion.x() + quaternion.x();
@@ -1393,6 +1404,7 @@ void QMatrix4x4::ortho(float left, float right, float bottom, float top, float n
const float width = right - left;
const float invheight = top - bottom;
const float clip = farPlane - nearPlane;
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = 2.0f / width;
m.m[1][0] = 0.0f;
@@ -1431,6 +1443,7 @@ void QMatrix4x4::frustum(float left, float right, float bottom, float top, float
return;
// Construct the projection.
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
const float width = right - left;
const float invheight = top - bottom;
@@ -1474,6 +1487,7 @@ void QMatrix4x4::perspective(float verticalAngle, float aspectRatio, float nearP
return;
// Construct the projection.
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
const float radians = qDegreesToRadians(verticalAngle / 2.0f);
const float sine = std::sin(radians);
@@ -1524,6 +1538,7 @@ void QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, const QVe
QVector3D side = QVector3D::crossProduct(forward, up).normalized();
QVector3D upVector = QVector3D::crossProduct(side, forward);
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = side.x();
m.m[1][0] = side.y();
@@ -1573,6 +1588,7 @@ void QMatrix4x4::viewport(float left, float bottom, float width, float height, f
const float w2 = width / 2.0f;
const float h2 = height / 2.0f;
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = w2;
m.m[1][0] = 0.0f;
@@ -1871,6 +1887,7 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
// of just rotations and translations.
QMatrix4x4 QMatrix4x4::orthonormalInverse() const
{
+ Q_DECL_UNINITIALIZED
QMatrix4x4 result(Qt::Uninitialized);
result.m[0][0] = m[0][0];
@@ -1943,6 +1960,7 @@ void QMatrix4x4::optimize()
flagBits &= ~Scale;
} else {
// If the columns are orthonormal and form a right-handed system, then there is no scale.
+ Q_DECL_UNINITIALIZED
double mm[4][4];
copyToDoubles(m, mm);
double det = matrixDet2(mm, 0, 1, 0, 1);
@@ -1957,6 +1975,7 @@ void QMatrix4x4::optimize()
}
} else {
// If the columns are orthonormal and form a right-handed system, then there is no scale.
+ Q_DECL_UNINITIALIZED
double mm[4][4];
copyToDoubles(m, mm);
double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2);
diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h
index 2ba274d4517..2a801905ce0 100644
--- a/src/gui/math3d/qmatrix4x4.h
+++ b/src/gui/math3d/qmatrix4x4.h
@@ -564,6 +564,7 @@ inline bool QMatrix4x4::operator!=(const QMatrix4x4& other) const
inline QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2)
{
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = m1.m[0][0] + m2.m[0][0];
m.m[0][1] = m1.m[0][1] + m2.m[0][1];
@@ -586,6 +587,7 @@ inline QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2)
inline QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2)
{
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = m1.m[0][0] - m2.m[0][0];
m.m[0][1] = m1.m[0][1] - m2.m[0][1];
@@ -608,21 +610,34 @@ inline QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2)
inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2)
{
+ Q_DECL_UNINITIALIZED
+ QMatrix4x4 m(Qt::Uninitialized);
QMatrix4x4::Flags flagBits = m1.flagBits | m2.flagBits;
if (flagBits.toInt() < QMatrix4x4::Rotation2D) {
- QMatrix4x4 m = m1;
- m.m[3][0] += m.m[0][0] * m2.m[3][0];
- m.m[3][1] += m.m[1][1] * m2.m[3][1];
- m.m[3][2] += m.m[2][2] * m2.m[3][2];
-
- m.m[0][0] *= m2.m[0][0];
- m.m[1][1] *= m2.m[1][1];
- m.m[2][2] *= m2.m[2][2];
+ // Scale | Translation
+ m.m[0][0] = m1.m[0][0] * m2.m[0][0];
+ m.m[0][1] = 0.0f;
+ m.m[0][2] = 0.0f;
+ m.m[0][3] = 0.0f;
+
+ m.m[1][0] = 0.0f;
+ m.m[1][1] = m1.m[1][1] * m2.m[1][1];
+ m.m[1][2] = 0.0f;
+ m.m[1][3] = 0.0f;
+
+ m.m[2][0] = 0.0f;
+ m.m[2][1] = 0.0f;
+ m.m[2][2] = m1.m[2][2] * m2.m[2][2];
+ m.m[2][3] = 0.0f;
+
+ m.m[3][0] = m1.m[3][0] + m1.m[0][0] * m2.m[3][0];
+ m.m[3][1] = m1.m[3][1] + m1.m[1][1] * m2.m[3][1];
+ m.m[3][2] = m1.m[3][2] + m1.m[2][2] * m2.m[3][2];
+ m.m[3][3] = 1.0f;
m.flagBits = flagBits;
return m;
}
- QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = m1.m[0][0] * m2.m[0][0]
+ m1.m[1][0] * m2.m[0][1]
+ m1.m[2][0] * m2.m[0][2]
@@ -843,6 +858,7 @@ inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point)
inline QMatrix4x4 operator-(const QMatrix4x4& matrix)
{
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = -matrix.m[0][0];
m.m[0][1] = -matrix.m[0][1];
@@ -865,6 +881,7 @@ inline QMatrix4x4 operator-(const QMatrix4x4& matrix)
inline QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix)
{
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = matrix.m[0][0] * factor;
m.m[0][1] = matrix.m[0][1] * factor;
@@ -887,6 +904,7 @@ inline QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix)
inline QMatrix4x4 operator*(const QMatrix4x4& matrix, float factor)
{
+ Q_DECL_UNINITIALIZED
QMatrix4x4 m(Qt::Uninitialized);
m.m[0][0] = matrix.m[0][0] * factor;
m.m[0][1] = matrix.m[0][1] * factor;
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp
index a675f59eb1f..57587322ea5 100644
--- a/src/gui/math3d/qquaternion.cpp
+++ b/src/gui/math3d/qquaternion.cpp
@@ -409,7 +409,7 @@ QQuaternion QQuaternion::fromAxisAndAngle
(float x, float y, float z, float angle)
{
float length = qHypot(x, y, z);
- if (!qFuzzyCompare(length, 1.0f) && !qFuzzyIsNull(length)) {
+ if (!qFuzzyIsNull(length) && !qFuzzyCompare(length, 1.0f)) {
x /= length;
y /= length;
z /= length;
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index a7b1d432df7..c92e7177199 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -305,10 +305,10 @@ constexpr QQuaternion operator/(const QQuaternion &quaternion, float divisor)
constexpr bool qFuzzyCompare(const QQuaternion &q1, const QQuaternion &q2) noexcept
{
- return qFuzzyCompare(q1.wp, q2.wp) &&
- qFuzzyCompare(q1.xp, q2.xp) &&
- qFuzzyCompare(q1.yp, q2.yp) &&
- qFuzzyCompare(q1.zp, q2.zp);
+ return QtPrivate::fuzzyCompare(q1.wp, q2.wp)
+ && QtPrivate::fuzzyCompare(q1.xp, q2.xp)
+ && QtPrivate::fuzzyCompare(q1.yp, q2.yp)
+ && QtPrivate::fuzzyCompare(q1.zp, q2.zp);
}
#if QT_GUI_INLINE_IMPL_SINCE(6, 11)
diff --git a/src/gui/math3d/qvectornd.cpp b/src/gui/math3d/qvectornd.cpp
index dcd7bdbcf80..ee070b2b5be 100644
--- a/src/gui/math3d/qvectornd.cpp
+++ b/src/gui/math3d/qvectornd.cpp
@@ -375,7 +375,8 @@ QT_BEGIN_NAMESPACE
*/
bool qFuzzyCompare(QVector2D v1, QVector2D v2) noexcept
{
- return qFuzzyCompare(v1.v[0], v2.v[0]) && qFuzzyCompare(v1.v[1], v2.v[1]);
+ return QtPrivate::fuzzyCompare(v1.v[0], v2.v[0])
+ && QtPrivate::fuzzyCompare(v1.v[1], v2.v[1]);
}
#ifndef QT_NO_VECTOR3D
@@ -467,7 +468,6 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector)
float x, y;
stream >> x;
stream >> y;
- Q_ASSERT(qIsFinite(x) && qIsFinite(y));
vector.setX(x);
vector.setY(y);
return stream;
@@ -980,9 +980,9 @@ QVector3D QVector3D::unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &pr
*/
bool qFuzzyCompare(QVector3D v1, QVector3D v2) noexcept
{
- return qFuzzyCompare(v1.v[0], v2.v[0]) &&
- qFuzzyCompare(v1.v[1], v2.v[1]) &&
- qFuzzyCompare(v1.v[2], v2.v[2]);
+ return QtPrivate::fuzzyCompare(v1.v[0], v2.v[0])
+ && QtPrivate::fuzzyCompare(v1.v[1], v2.v[1])
+ && QtPrivate::fuzzyCompare(v1.v[2], v2.v[2]);
}
#ifndef QT_NO_VECTOR2D
@@ -1098,7 +1098,6 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector)
stream >> x;
stream >> y;
stream >> z;
- Q_ASSERT(qIsFinite(x) && qIsFinite(y) && qIsFinite(z));
vector.setX(x);
vector.setY(y);
vector.setZ(z);
@@ -1503,10 +1502,10 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector)
*/
bool qFuzzyCompare(QVector4D v1, QVector4D v2) noexcept
{
- return qFuzzyCompare(v1.v[0], v2.v[0]) &&
- qFuzzyCompare(v1.v[1], v2.v[1]) &&
- qFuzzyCompare(v1.v[2], v2.v[2]) &&
- qFuzzyCompare(v1.v[3], v2.v[3]);
+ return QtPrivate::fuzzyCompare(v1.v[0], v2.v[0])
+ && QtPrivate::fuzzyCompare(v1.v[1], v2.v[1])
+ && QtPrivate::fuzzyCompare(v1.v[2], v2.v[2])
+ && QtPrivate::fuzzyCompare(v1.v[3], v2.v[3]);
}
#ifndef QT_NO_VECTOR2D
@@ -1627,7 +1626,6 @@ QDataStream &operator>>(QDataStream &stream, QVector4D &vector)
stream >> y;
stream >> z;
stream >> w;
- Q_ASSERT(qIsFinite(x) && qIsFinite(y) && qIsFinite(z) && qIsFinite(w));
vector.setX(x);
vector.setY(y);
vector.setZ(z);
diff --git a/src/gui/opengl/platform/egl/qeglplatformcontext.cpp b/src/gui/opengl/platform/egl/qeglplatformcontext.cpp
index e56504833d1..350968b87d4 100644
--- a/src/gui/opengl/platform/egl/qeglplatformcontext.cpp
+++ b/src/gui/opengl/platform/egl/qeglplatformcontext.cpp
@@ -104,6 +104,14 @@ QT_BEGIN_NAMESPACE
#define GL_LOSE_CONTEXT_ON_RESET 0x8252
#endif
+// Constants from GL_EXT_robustness.
+#ifndef GL_RESET_NOTIFICATION_STRATEGY_EXT
+#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
+#endif
+#ifndef GL_LOSE_CONTEXT_ON_RESET_EXT
+#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
+#endif
+
// Constants from EGL_NV_robustness_video_memory_purge
#ifndef EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV
#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
@@ -452,11 +460,16 @@ void QEGLPlatformContext::updateFormatFromGL()
}
}
}
- if (hasExtension("GL_ARB_robustness")) {
+ if (m_format.renderableType() == QSurfaceFormat::OpenGL && hasExtension("GL_ARB_robustness")) {
GLint value = 0;
glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &value);
if (value == GL_LOSE_CONTEXT_ON_RESET)
m_format.setOption(QSurfaceFormat::ResetNotification);
+ } else if (m_format.renderableType() == QSurfaceFormat::OpenGLES && hasExtension("GL_EXT_robustness")) {
+ GLint value = 0;
+ glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_EXT, &value);
+ if (value == GL_LOSE_CONTEXT_ON_RESET_EXT)
+ m_format.setOption(QSurfaceFormat::ResetNotification);
}
}
runGLChecks();
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 6b45d26fb4c..cb927d7c296 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -192,6 +192,12 @@ QOpenGLFunctions::QOpenGLFunctions(QOpenGLContext *context)
qWarning("QOpenGLFunctions created with non-current context");
}
+/*!
+ \class QOpenGLExtensions
+ \inmodule QtGui
+ \internal
+*/
+
QOpenGLExtensions::QOpenGLExtensions()
{
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 04433c7703a..697ede42d92 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -930,7 +930,7 @@ static inline bool canUseFastMatrixPath(const qreal cx, const qreal cy, const qs
minc = std::min(minc, std::min(fx, fy));
maxc = std::max(maxc, std::max(fx, fy));
- return minc >= std::numeric_limits<int>::min() && maxc <= std::numeric_limits<int>::max();
+ return minc >= std::numeric_limits<int>::min() && maxc <= qreal(std::numeric_limits<int>::max());
}
template<TextureBlendType blendType, QPixelLayout::BPP bpp, typename T>
@@ -5179,7 +5179,7 @@ static inline bool calculate_fixed_gradient_factors(int count, const QT_FT_Span
const int gss = GRADIENT_STOPTABLE_SIZE - 1;
qreal ryinc = linear.dy * data->m22 * gss * FIXPT_SIZE;
qreal roff = (linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss * FIXPT_SIZE;
- const int limit = std::numeric_limits<int>::max() - FIXPT_SIZE;
+ const qreal limit = qreal(std::numeric_limits<int>::max() - FIXPT_SIZE);
if (count && (std::fabs(ryinc) < limit) && (std::fabs(roff) < limit)
&& (std::fabs(ryinc * spans->y + roff) < limit)
&& (std::fabs(ryinc * (spans + count - 1)->y + roff) < limit)) {
diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp
index e6f346dcdf2..17fb6491b75 100644
--- a/src/gui/painting/qpagelayout.cpp
+++ b/src/gui/painting/qpagelayout.cpp
@@ -606,7 +606,7 @@ bool QPageLayout::setLeftMargin(qreal leftMargin, OutOfBoundsPolicy outOfBoundsP
if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp)
leftMargin = qBound(d->m_minMargins.left(), leftMargin, d->m_maxMargins.left());
- if (qFuzzyCompare(leftMargin, d->m_margins.left()))
+ if (QtPrivate::fuzzyCompare(leftMargin, d->m_margins.left()))
return true;
if (d->m_mode == FullPageMode
@@ -637,7 +637,7 @@ bool QPageLayout::setRightMargin(qreal rightMargin, OutOfBoundsPolicy outOfBound
if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp)
rightMargin = qBound(d->m_minMargins.right(), rightMargin, d->m_maxMargins.right());
- if (qFuzzyCompare(rightMargin, d->m_margins.right()))
+ if (QtPrivate::fuzzyCompare(rightMargin, d->m_margins.right()))
return true;
if (d->m_mode == FullPageMode
@@ -668,7 +668,7 @@ bool QPageLayout::setTopMargin(qreal topMargin, OutOfBoundsPolicy outOfBoundsPol
if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp)
topMargin = qBound(d->m_minMargins.top(), topMargin, d->m_maxMargins.top());
- if (qFuzzyCompare(topMargin, d->m_margins.top()))
+ if (QtPrivate::fuzzyCompare(topMargin, d->m_margins.top()))
return true;
if (d->m_mode == FullPageMode
@@ -699,7 +699,7 @@ bool QPageLayout::setBottomMargin(qreal bottomMargin, OutOfBoundsPolicy outOfBou
if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp)
bottomMargin = qBound(d->m_minMargins.bottom(), bottomMargin, d->m_maxMargins.bottom());
- if (qFuzzyCompare(bottomMargin, d->m_margins.bottom()))
+ if (QtPrivate::fuzzyCompare(bottomMargin, d->m_margins.bottom()))
return true;
if (d->m_mode == FullPageMode
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 74321705ff5..8e815394849 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2881,6 +2881,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
/*!
+ * \internal
* Returns \c true if the rectangle is completely within the current clip
* state of the paint engine.
*/
@@ -2952,9 +2953,9 @@ inline bool QRasterPaintEnginePrivate::isUnclipped(const QRectF &rect,
int penWidth) const
{
const QRectF norm = rect.normalized();
- if (norm.left() <= INT_MIN || norm.top() <= INT_MIN
- || norm.right() > INT_MAX || norm.bottom() > INT_MAX
- || norm.width() > INT_MAX || norm.height() > INT_MAX)
+ if (norm.left() <= qreal(INT_MIN) || norm.top() <= qreal(INT_MIN)
+ || norm.right() > qreal(INT_MAX) || norm.bottom() > qreal(INT_MAX)
+ || norm.width() > qreal(INT_MAX) || norm.height() > qreal(INT_MAX))
return false;
return isUnclipped(norm.toAlignedRect(), penWidth);
}
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index cc80641ded9..ab9e7fe312a 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -6,9 +6,11 @@
#include <QtGui/qtguiglobal.h>
#include <QtGui/qtransform.h>
+
#include <QtCore/qglobal.h>
#include <QtCore/qline.h>
#include <QtCore/qlist.h>
+#include <QtCore/qpoint.h>
#include <QtCore/qrect.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 908051a477c..b1ea3f240f1 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -3192,6 +3192,7 @@ static inline bool is_monochrome(const QList<QRgb> &colorTable)
}
/*!
+ * \internal
* Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
*/
int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, bool lossless, qint64 serial_no)
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 0d435c95048..08128c30a70 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -145,6 +145,11 @@ static inline qreal adapted_angle_on_x(const QLineF &line)
return QLineF(0, 0, 1, 0).angleTo(line);
}
+/*!
+ \class QStrokerOps
+ \inmodule QtGui
+ \internal
+*/
QStrokerOps::QStrokerOps()
: m_elements(0)
, m_curveThreshold(qt_real_to_fixed(0.25))
@@ -373,6 +378,7 @@ QStroker::LineJoinMode QStroker::joinModeForJoin(Qt::PenJoinStyle joinStyle)
/*!
+ \internal
This function is called to stroke the currently built up
subpath. The subpath is cleared when the function completes.
*/
diff --git a/src/gui/platform/unix/dbusmenu/qdbusplatformmenu.cpp b/src/gui/platform/unix/dbusmenu/qdbusplatformmenu.cpp
index fe050461260..00c3192e00a 100644
--- a/src/gui/platform/unix/dbusmenu/qdbusplatformmenu.cpp
+++ b/src/gui/platform/unix/dbusmenu/qdbusplatformmenu.cpp
@@ -48,6 +48,7 @@ void QDBusPlatformMenuItem::setIcon(const QIcon &icon)
}
/*!
+ \internal
Set a submenu under this menu item.
*/
void QDBusPlatformMenuItem::setMenu(QPlatformMenu *menu)
diff --git a/src/gui/platform/unix/qxkbcommon.cpp b/src/gui/platform/unix/qxkbcommon.cpp
index ebac9f108e8..e755892cf36 100644
--- a/src/gui/platform/unix/qxkbcommon.cpp
+++ b/src/gui/platform/unix/qxkbcommon.cpp
@@ -328,6 +328,12 @@ static constexpr const auto KeyTbl = qMakeArray(
Xkb2Qt<XKB_KEY_XF86Option, Qt::Key_Option>,
Xkb2Qt<XKB_KEY_XF86Paste, Qt::Key_Paste>,
Xkb2Qt<XKB_KEY_XF86Phone, Qt::Key_Phone>,
+#ifdef XKB_KEY_XF86PickupPhone
+ Xkb2Qt<XKB_KEY_XF86PickupPhone, Qt::Key_Call>,
+#endif
+#ifdef XKB_KEY_XF86HangupPhone
+ Xkb2Qt<XKB_KEY_XF86HangupPhone, Qt::Key_Hangup>,
+#endif
Xkb2Qt<XKB_KEY_XF86Reply, Qt::Key_Reply>,
Xkb2Qt<XKB_KEY_XF86Reload, Qt::Key_Reload>,
Xkb2Qt<XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows>,
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 7fa05f69232..0d4ce909daa 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -26,6 +26,8 @@
#include <Metal/Metal.h>
+#include <utility> // for std::pair
+
QT_BEGIN_NAMESPACE
/*
@@ -1674,12 +1676,12 @@ void QRhiMetal::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
if (needsBufferSizeBuffer) {
QMetalBuffer *bufD = nullptr;
- QVarLengthArray<QPair<QMetalShader *, QRhiShaderResourceBinding::StageFlag>, 4> shaders;
+ QVarLengthArray<std::pair<QMetalShader *, QRhiShaderResourceBinding::StageFlag>, 4> shaders;
if (compPsD) {
bufD = compPsD->d->bufferSizeBuffer;
Q_ASSERT(compPsD->d->cs.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding));
- shaders.append(qMakePair(&compPsD->d->cs, QRhiShaderResourceBinding::StageFlag::ComputeStage));
+ shaders.append({&compPsD->d->cs, QRhiShaderResourceBinding::StageFlag::ComputeStage});
} else {
bufD = gfxPsD->d->bufferSizeBuffer;
if (gfxPsD->d->tess.enabled) {
@@ -1706,24 +1708,24 @@ void QRhiMetal::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
== gfxPsD->d->tess.compVs[2].nativeShaderInfo.extraBufferBindings[QShaderPrivate::MslBufferSizeBufferBinding]);
if (gfxPsD->d->tess.compVs[0].nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding))
- shaders.append(qMakePair(&gfxPsD->d->tess.compVs[0], QRhiShaderResourceBinding::StageFlag::VertexStage));
+ shaders.append({&gfxPsD->d->tess.compVs[0], QRhiShaderResourceBinding::StageFlag::VertexStage});
if (gfxPsD->d->tess.compTesc.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding))
- shaders.append(qMakePair(&gfxPsD->d->tess.compTesc, QRhiShaderResourceBinding::StageFlag::TessellationControlStage));
+ shaders.append({&gfxPsD->d->tess.compTesc, QRhiShaderResourceBinding::StageFlag::TessellationControlStage});
if (gfxPsD->d->tess.vertTese.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding))
- shaders.append(qMakePair(&gfxPsD->d->tess.vertTese, QRhiShaderResourceBinding::StageFlag::TessellationEvaluationStage));
+ shaders.append({&gfxPsD->d->tess.vertTese, QRhiShaderResourceBinding::StageFlag::TessellationEvaluationStage});
} else {
if (gfxPsD->d->vs.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding))
- shaders.append(qMakePair(&gfxPsD->d->vs, QRhiShaderResourceBinding::StageFlag::VertexStage));
+ shaders.append({&gfxPsD->d->vs, QRhiShaderResourceBinding::StageFlag::VertexStage});
}
if (gfxPsD->d->fs.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding))
- shaders.append(qMakePair(&gfxPsD->d->fs, QRhiShaderResourceBinding::StageFlag::FragmentStage));
+ shaders.append({&gfxPsD->d->fs, QRhiShaderResourceBinding::StageFlag::FragmentStage});
}
quint32 offset = 0;
- for (const QPair<QMetalShader *, QRhiShaderResourceBinding::StageFlag> &shader : shaders) {
+ for (const auto &shader : shaders) {
const int binding = shader.first->nativeShaderInfo.extraBufferBindings[QShaderPrivate::MslBufferSizeBufferBinding];
@@ -6030,7 +6032,7 @@ bool QMetalGraphicsPipeline::create()
for (QMetalShader *shader : shaders) {
if (shader->nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)) {
const int binding = shader->nativeShaderInfo.extraBufferBindings[QShaderPrivate::MslBufferSizeBufferBinding];
- shader->nativeResourceBindingMap[binding] = qMakePair(binding, -1);
+ shader->nativeResourceBindingMap[binding] = {binding, -1};
int maxNativeBinding = 0;
for (const QShaderDescription::StorageBlock &block : shader->desc.storageBlocks())
maxNativeBinding = qMax(maxNativeBinding, shader->nativeResourceBindingMap[block.binding].first);
@@ -6148,7 +6150,7 @@ bool QMetalComputePipeline::create()
// SPIRV-Cross buffer size buffers
if (d->cs.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)) {
const int binding = d->cs.nativeShaderInfo.extraBufferBindings[QShaderPrivate::MslBufferSizeBufferBinding];
- d->cs.nativeResourceBindingMap[binding] = qMakePair(binding, -1);
+ d->cs.nativeResourceBindingMap[binding] = {binding, -1};
}
if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) {
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index a511eb854cb..202e28263c2 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -682,6 +682,12 @@ bool QRhiVulkan::create(QRhi::Flags flags)
if (devExts.contains("VK_KHR_fragment_shading_rate"))
addToChain(&physDevFeaturesChainable, &fragmentShadingRateFeatures);
#endif
+#ifdef VK_EXT_device_fault
+ VkPhysicalDeviceFaultFeaturesEXT deviceFaultFeatures = {};
+ deviceFaultFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT;
+ if (devExts.contains(VK_EXT_DEVICE_FAULT_EXTENSION_NAME))
+ addToChain(&physDevFeaturesChainable, &deviceFaultFeatures);
+#endif
#endif
// Vulkan >=1.2 headers at build time, >=1.2 implementation at run time
@@ -825,6 +831,13 @@ bool QRhiVulkan::create(QRhi::Flags flags)
requestedDevExts.append(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
#endif
+#ifdef VK_EXT_device_fault
+ if (devExts.contains(VK_EXT_DEVICE_FAULT_EXTENSION_NAME)) {
+ requestedDevExts.append(VK_EXT_DEVICE_FAULT_EXTENSION_NAME);
+ caps.deviceFault = true;
+ }
+#endif
+
for (const QByteArray &ext : requestedDeviceExtensions) {
if (!ext.isEmpty() && !requestedDevExts.contains(ext)) {
if (devExts.contains(ext)) {
@@ -910,6 +923,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
// Here we have no way to tell if the extensions got enabled or not.
// Pretend it's all there and supported. If getProcAddress fails, we'll
// handle that gracefully.
+ caps.deviceFault = true;
caps.vertexAttribDivisor = true;
caps.renderPass2KHR = true;
caps.depthStencilResolveKHR = true;
@@ -1126,6 +1140,12 @@ bool QRhiVulkan::create(QRhi::Flags flags)
}
#endif
+#ifdef VK_EXT_device_fault
+ if (caps.deviceFault) {
+ vkGetDeviceFaultInfoEXT = reinterpret_cast<PFN_vkGetDeviceFaultInfoEXT>(f->vkGetDeviceProcAddr(dev, "vkGetDeviceFaultInfoEXT"));
+ }
+#endif
+
deviceLost = false;
nativeHandlesStruct.physDev = physDev;
@@ -2159,6 +2179,18 @@ bool QRhiVulkan::createOffscreenRenderPass(QVkRenderPassDescriptor *rpD,
}
#endif
+ // Add self-dependency to be able to add memory barriers for writes in graphics stages
+ VkSubpassDependency selfDependency;
+ VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
+ selfDependency.srcSubpass = 0;
+ selfDependency.dstSubpass = 0;
+ selfDependency.srcStageMask = stageMask;
+ selfDependency.dstStageMask = stageMask;
+ selfDependency.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ selfDependency.dstAccessMask = selfDependency.srcAccessMask;
+ selfDependency.dependencyFlags = 0;
+ rpD->subpassDeps.append(selfDependency);
+
// rpD->subpassDeps stays empty: don't yet know the correct initial/final
// access and stage stuff for the implicit deps at this point, so leave it
// to the resource tracking and activateTextureRenderTarget() to generate
@@ -2631,6 +2663,7 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin
} else {
if (err == VK_ERROR_DEVICE_LOST) {
qWarning("Device loss detected in vkAcquireNextImageKHR()");
+ printExtraErrorInfo(err);
deviceLost = true;
return QRhi::FrameOpDeviceLost;
}
@@ -2791,6 +2824,7 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram
} else if (err != VK_SUBOPTIMAL_KHR) {
if (err == VK_ERROR_DEVICE_LOST) {
qWarning("Device loss detected in vkQueuePresentKHR()");
+ printExtraErrorInfo(err);
deviceLost = true;
return QRhi::FrameOpDeviceLost;
}
@@ -2850,6 +2884,7 @@ QRhi::FrameOpResult QRhiVulkan::startPrimaryCommandBuffer(VkCommandBuffer *cb)
if (err != VK_SUCCESS) {
if (err == VK_ERROR_DEVICE_LOST) {
qWarning("Device loss detected in vkAllocateCommandBuffers()");
+ printExtraErrorInfo(err);
deviceLost = true;
return QRhi::FrameOpDeviceLost;
}
@@ -2865,6 +2900,7 @@ QRhi::FrameOpResult QRhiVulkan::startPrimaryCommandBuffer(VkCommandBuffer *cb)
if (err != VK_SUCCESS) {
if (err == VK_ERROR_DEVICE_LOST) {
qWarning("Device loss detected in vkBeginCommandBuffer()");
+ printExtraErrorInfo(err);
deviceLost = true;
return QRhi::FrameOpDeviceLost;
}
@@ -2882,6 +2918,7 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer
if (err != VK_SUCCESS) {
if (err == VK_ERROR_DEVICE_LOST) {
qWarning("Device loss detected in vkEndCommandBuffer()");
+ printExtraErrorInfo(err);
deviceLost = true;
return QRhi::FrameOpDeviceLost;
}
@@ -2918,6 +2955,7 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer
if (err != VK_SUCCESS) {
if (err == VK_ERROR_DEVICE_LOST) {
qWarning("Device loss detected in vkQueueSubmit()");
+ printExtraErrorInfo(err);
deviceLost = true;
return QRhi::FrameOpDeviceLost;
}
@@ -2939,6 +2977,7 @@ QRhi::FrameOpResult QRhiVulkan::waitCommandCompletion(int frameSlot)
if (err != VK_SUCCESS) {
if (err == VK_ERROR_DEVICE_LOST) {
qWarning("Device loss detected in vkWaitForFences()");
+ printExtraErrorInfo(err);
deviceLost = true;
return QRhi::FrameOpDeviceLost;
}
@@ -4067,10 +4106,87 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level,
void QRhiVulkan::printExtraErrorInfo(VkResult err)
{
+ if (err == VK_ERROR_DEVICE_LOST)
+ printDeviceLossErrorInfo();
if (err == VK_ERROR_OUT_OF_DEVICE_MEMORY)
qWarning() << "Out of device memory, current allocator statistics are" << statistics();
}
+void QRhiVulkan::printDeviceLossErrorInfo() const
+{
+#ifdef VK_EXT_device_fault
+ if (!dev || !caps.deviceFault || !vkGetDeviceFaultInfoEXT)
+ return;
+
+ VkDeviceFaultCountsEXT faultCounts{};
+ faultCounts.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT;
+ faultCounts.pNext = nullptr;
+
+ VkResult result = vkGetDeviceFaultInfoEXT(dev, &faultCounts, nullptr);
+ if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
+ qWarning("vkGetDeviceFaultInfoEXT failed with %d", result);
+ return;
+ }
+ faultCounts.vendorBinarySize = 0;
+
+ QVarLengthArray<VkDeviceFaultAddressInfoEXT> addressInfos;
+ addressInfos.resize(faultCounts.addressInfoCount);
+
+ QVarLengthArray<VkDeviceFaultVendorInfoEXT> vendorInfos;
+ vendorInfos.resize(faultCounts.vendorInfoCount);
+
+ VkDeviceFaultInfoEXT info{};
+ info.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT;
+ info.pNext = nullptr;
+ info.pAddressInfos = addressInfos.isEmpty() ? nullptr : addressInfos.data();
+ info.pVendorInfos = vendorInfos.isEmpty() ? nullptr : vendorInfos.data();
+ info.pVendorBinaryData = nullptr;
+
+ result = vkGetDeviceFaultInfoEXT(dev, &faultCounts, &info);
+ if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
+ qWarning("vkGetDeviceFaultInfoEXT failed with %d", result);
+ return;
+ }
+
+ const char *desc = info.description[0] ? info.description : "n/a";
+ qWarning("VK_ERROR_DEVICE_LOST (VK_EXT_device_fault): %u address infos, %u vendor infos, %llu bytes vendor binary: %s",
+ faultCounts.addressInfoCount,
+ faultCounts.vendorInfoCount,
+ (unsigned long long)faultCounts.vendorBinarySize,
+ desc);
+
+ for (uint32_t i = 0; i < faultCounts.addressInfoCount; ++i) {
+ const auto &a = addressInfos[i];
+ auto addressTypeString = [](const VkDeviceFaultAddressTypeEXT type) {
+ switch (type) {
+ case VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT: return "NONE";
+ case VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT: return "READ_INVALID";
+ case VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT: return "WRITE_INVALID";
+ case VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT: return "EXECUTE_INVALID";
+ case VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT: return "INSTRUCTION_POINTER_UNKNOWN";
+ case VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT: return "INSTRUCTION_POINTER_INVALID";
+ case VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT: return "INSTRUCTION_POINTER_FAULT";
+ default: return "UNKNOWN";
+ };
+ };
+ qWarning(" AddressInfo[%02u]: type=%s addr=0x%llx precision=%llu",
+ i,
+ addressTypeString(a.addressType),
+ (unsigned long long)a.reportedAddress,
+ (unsigned long long)a.addressPrecision);
+ }
+
+ for (uint32_t i = 0; i < faultCounts.vendorInfoCount; ++i) {
+ const auto &v = vendorInfos[i];
+ qWarning(" VendorInfo[%02u]: code=%llu data=%llu desc=%s",
+ i,
+ (unsigned long long)v.vendorFaultCode,
+ (unsigned long long)v.vendorFaultData,
+ v.description);
+ }
+#endif // VK_EXT_device_fault
+}
+
void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates)
{
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
@@ -4864,6 +4980,17 @@ void QRhiVulkan::recordPrimaryCommandBuffer(QVkCommandBuffer *cbD)
cmd.args.beginRenderPass.useSecondaryCb ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS
: VK_SUBPASS_CONTENTS_INLINE);
break;
+ case QVkCommandBuffer::Command::MemoryBarrier: {
+ VkMemoryBarrier barrier;
+ barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+ barrier.pNext = nullptr;
+ barrier.dstAccessMask = cmd.args.memoryBarrier.dstAccessMask;
+ barrier.srcAccessMask = cmd.args.memoryBarrier.srcAccessMask;
+ df->vkCmdPipelineBarrier(cbD->cb, cmd.args.memoryBarrier.srcStageMask, cmd.args.memoryBarrier.dstStageMask, cmd.args.memoryBarrier.dependencyFlags,
+ 1, &barrier,
+ 0, VK_NULL_HANDLE,
+ 0, VK_NULL_HANDLE);
+ } break;
case QVkCommandBuffer::Command::EndRenderPass:
df->vkCmdEndRenderPass(cbD->cb);
break;
@@ -5702,6 +5829,9 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
QVkShaderResourceBindings *srbD = QRHI_RES(QVkShaderResourceBindings, srb);
auto &descSetBd(srbD->boundResourceData[currentFrameSlot]);
bool rewriteDescSet = false;
+ bool addWriteBarrier = false;
+ VkPipelineStageFlags writeBarrierSrcStageMask = 0;
+ VkPipelineStageFlags writeBarrierDstStageMask = 0;
// Do host writes and mark referenced shader resources as in-use.
// Also prepare to ensure the descriptor set we are going to bind refers to up-to-date Vk objects.
@@ -5789,9 +5919,22 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
access = QRhiPassResourceTracker::TexStorageStore;
else
access = QRhiPassResourceTracker::TexStorageLoadStore;
+
+ const auto stage = QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage);
+ const auto prevAccess = passResTracker.textures().find(texD);
+ if (prevAccess != passResTracker.textures().end()) {
+ const QRhiPassResourceTracker::Texture &tex = prevAccess->second;
+ if (tex.access == QRhiPassResourceTracker::TexStorageStore
+ || tex.access == QRhiPassResourceTracker::TexStorageLoadStore) {
+ addWriteBarrier = true;
+ writeBarrierDstStageMask |= toVkPipelineStage(stage);
+ writeBarrierSrcStageMask |= toVkPipelineStage(tex.stage);
+ }
+ }
+
trackedRegisterTexture(&passResTracker, texD,
access,
- QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage));
+ stage);
if (texD->generation != bd.simage.generation || texD->m_id != bd.simage.id) {
rewriteDescSet = true;
@@ -5818,9 +5961,21 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
access = QRhiPassResourceTracker::BufStorageStore;
else
access = QRhiPassResourceTracker::BufStorageLoadStore;
+
+ const auto stage = QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage);
+ const auto prevAccess = passResTracker.buffers().find(bufD);
+ if (prevAccess != passResTracker.buffers().end()) {
+ const QRhiPassResourceTracker::Buffer &buf = prevAccess->second;
+ if (buf.access == QRhiPassResourceTracker::BufStorageStore
+ || buf.access == QRhiPassResourceTracker::BufStorageLoadStore) {
+ addWriteBarrier = true;
+ writeBarrierDstStageMask |= toVkPipelineStage(stage);
+ writeBarrierSrcStageMask |= toVkPipelineStage(buf.stage);
+ }
+ }
trackedRegisterBuffer(&passResTracker, bufD, bufD->m_type == QRhiBuffer::Dynamic ? currentFrameSlot : 0,
access,
- QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage));
+ stage);
if (bufD->generation != bd.sbuf.generation || bufD->m_id != bd.sbuf.id) {
rewriteDescSet = true;
@@ -5835,6 +5990,28 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
}
}
+ if (addWriteBarrier) {
+ if (cbD->passUsesSecondaryCb) {
+ VkMemoryBarrier barrier;
+ barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+ barrier.pNext = nullptr;
+ barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ barrier.srcAccessMask = barrier.dstAccessMask;
+ df->vkCmdPipelineBarrier(cbD->activeSecondaryCbStack.last(), writeBarrierSrcStageMask, writeBarrierDstStageMask, 0,
+ 1, &barrier,
+ 0, VK_NULL_HANDLE,
+ 0, VK_NULL_HANDLE);
+ } else {
+ QVkCommandBuffer::Command &cmd(cbD->commands.get());
+ cmd.cmd = QVkCommandBuffer::Command::MemoryBarrier;
+ cmd.args.memoryBarrier.dependencyFlags = 0;
+ cmd.args.memoryBarrier.dstStageMask = writeBarrierDstStageMask;
+ cmd.args.memoryBarrier.srcStageMask = writeBarrierSrcStageMask;
+ cmd.args.memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
+ cmd.args.memoryBarrier.srcAccessMask = cmd.args.memoryBarrier.dstAccessMask;
+ }
+ }
+
// write descriptor sets, if needed
if (rewriteDescSet)
updateShaderResourceBindings(srb);
diff --git a/src/gui/rhi/qrhivulkan_p.h b/src/gui/rhi/qrhivulkan_p.h
index 1e9318513fd..eb07d8be448 100644
--- a/src/gui/rhi/qrhivulkan_p.h
+++ b/src/gui/rhi/qrhivulkan_p.h
@@ -425,7 +425,8 @@ struct QVkCommandBuffer : public QRhiCommandBuffer
TransitionPassResources,
Dispatch,
ExecuteSecondary,
- SetShadingRate
+ SetShadingRate,
+ MemoryBarrier
};
Cmd cmd;
@@ -464,6 +465,13 @@ struct QVkCommandBuffer : public QRhiCommandBuffer
struct {
VkPipelineStageFlags srcStageMask;
VkPipelineStageFlags dstStageMask;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+ VkDependencyFlags dependencyFlags;
+ } memoryBarrier;
+ struct {
+ VkPipelineStageFlags srcStageMask;
+ VkPipelineStageFlags dstStageMask;
int count;
int index;
} bufferBarrier;
@@ -874,6 +882,7 @@ public:
void ensureCommandPoolForNewFrame();
double elapsedSecondsFromTimestamp(quint64 timestamp[2], bool *ok);
void printExtraErrorInfo(VkResult err);
+ void printDeviceLossErrorInfo() const;
QVulkanInstance *inst = nullptr;
QWindow *maybeWindow = nullptr;
@@ -934,11 +943,16 @@ public:
PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr;
#endif
+#ifdef VK_EXT_device_fault
+ PFN_vkGetDeviceFaultInfoEXT vkGetDeviceFaultInfoEXT = nullptr;
+#endif
+
struct {
bool compute = false;
bool depthClamp = false;
bool wideLines = false;
bool debugUtils = false;
+ bool deviceFault = false;
bool vertexAttribDivisor = false;
bool texture3DSliceAs2D = false;
bool tessellation = false;
diff --git a/src/gui/text/freetype/qfontengine_ft.cpp b/src/gui/text/freetype/qfontengine_ft.cpp
index 63d9c2893dc..e331a4cc815 100644
--- a/src/gui/text/freetype/qfontengine_ft.cpp
+++ b/src/gui/text/freetype/qfontengine_ft.cpp
@@ -1225,7 +1225,7 @@ static inline QTransform FTAffineToQTransform(const FT_Affine23 &matrix)
}
bool QFontEngineFT::traverseColr1(FT_OpaquePaint opaquePaint,
- QSet<QPair<FT_Byte *, FT_Bool> > *loops,
+ QSet<std::pair<FT_Byte *, FT_Bool> > *loops,
QColor foregroundColor,
FT_Color *palette,
ushort paletteCount,
@@ -1233,7 +1233,7 @@ bool QFontEngineFT::traverseColr1(FT_OpaquePaint opaquePaint,
{
FT_Face face = freetype->face;
- auto key = qMakePair(opaquePaint.p, opaquePaint.insert_root_transform);
+ auto key = std::pair{opaquePaint.p, opaquePaint.insert_root_transform};
if (loops->contains(key)) {
qCWarning(lcColrv1) << "Cycle detected in COLRv1 graph";
return false;
@@ -1680,7 +1680,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadColrv1Glyph(QGlyphSet *set,
// Do a pass over the graph to find the bounds
QColrPaintGraphRenderer boundingRectCalculator;
boundingRectCalculator.beginCalculateBoundingBox();
- QSet<QPair<FT_Byte *, FT_Bool> > loops;
+ QSet<std::pair<FT_Byte *, FT_Bool> > loops;
if (traverseColr1(opaquePaint,
&loops,
QColor{},
@@ -1735,7 +1735,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadColrv1Glyph(QGlyphSet *set,
originalXform);
// Render
- QSet<QPair<FT_Byte *, FT_Bool> > loops;
+ QSet<std::pair<FT_Byte *, FT_Bool> > loops;
if (!traverseColr1(opaquePaint,
&loops,
foregroundColor,
diff --git a/src/gui/text/freetype/qfontengine_ft_p.h b/src/gui/text/freetype/qfontengine_ft_p.h
index fc07693ef6a..13cd1bf2bfa 100644
--- a/src/gui/text/freetype/qfontengine_ft_p.h
+++ b/src/gui/text/freetype/qfontengine_ft_p.h
@@ -34,6 +34,8 @@
#include <string.h>
#include <qpainterpath.h>
+#include <utility> // for std::pair
+
QT_BEGIN_NAMESPACE
class QFontEngineFTRawFont;
@@ -333,7 +335,7 @@ private:
bool fetchMetricsOnly) const;
bool traverseColr1(FT_OpaquePaint paint,
- QSet<QPair<FT_Byte *, FT_Bool> > *loops,
+ QSet<std::pair<FT_Byte *, FT_Bool> > *loops,
QColor foregroundColor,
FT_Color *palette,
ushort paletteCount,
diff --git a/src/gui/text/qcolrpaintgraphrenderer.cpp b/src/gui/text/qcolrpaintgraphrenderer.cpp
index 9041e804753..bc439021eb1 100644
--- a/src/gui/text/qcolrpaintgraphrenderer.cpp
+++ b/src/gui/text/qcolrpaintgraphrenderer.cpp
@@ -180,7 +180,7 @@ void QColrPaintGraphRenderer::setConicalGradient(QPointF center,
adaptedStops.reserve(gradientStops.size());
for (const QGradientStop &gradientStop : gradientStops)
- adaptedStops.append(qMakePair(gradientStop.first * multiplier, gradientStop.second));
+ adaptedStops.append({gradientStop.first * multiplier, gradientStop.second});
conicalGradient.setStops(adaptedStops);
conicalGradient.setCoordinateMode(QGradient::LogicalMode);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 2b2f2a27fcd..ba49d538c2c 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -31,6 +31,7 @@
#include <QtCore/QMutexLocker>
#include <QtCore/QMutex>
+#include <algorithm>
#include <array>
// #define QFONTCACHE_DEBUG
@@ -1853,35 +1854,13 @@ bool QFont::operator<(const QFont &f) const
int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning;
if (f1attrs != f2attrs) return f1attrs < f2attrs;
- if (d->features.size() != f.d->features.size())
- return f.d->features.size() < d->features.size();
-
- {
- auto it = d->features.constBegin();
- auto jt = f.d->features.constBegin();
- for (; it != d->features.constEnd(); ++it, ++jt) {
- if (it.key() != jt.key())
- return jt.key() < it.key();
- if (it.value() != jt.value())
- return jt.value() < it.value();
- }
+ if (d->features != f.d->features) {
+ return std::lexicographical_compare(f.d->features.keyValueBegin(), f.d->features.keyValueEnd(),
+ d->features.keyValueBegin(), d->features.keyValueEnd());
}
- if (r1.variableAxisValues.size() != r2.variableAxisValues.size())
- return r1.variableAxisValues.size() < r2.variableAxisValues.size();
-
- {
- auto it = r1.variableAxisValues.constBegin();
- auto jt = r2.variableAxisValues.constBegin();
- for (; it != r1.variableAxisValues.constEnd(); ++it, ++jt) {
- if (it.key() != jt.key())
- return jt.key() < it.key();
- if (it.value() != jt.value())
- return jt.value() < it.value();
- }
- }
-
- return false;
+ return std::lexicographical_compare(r1.variableAxisValues.keyValueBegin(), r1.variableAxisValues.keyValueEnd(),
+ r2.variableAxisValues.keyValueBegin(), r2.variableAxisValues.keyValueEnd());
}
@@ -2170,6 +2149,7 @@ QString QFont::key() const
\li Style strategy
\li Font style
\li Font features
+ \li Variable axes
\endlist
\sa fromString()
@@ -2195,12 +2175,12 @@ QString QFont::toString() const
QString::number((int)styleStrategy()) + comma +
styleName();
- QMap<Tag, quint32> sortedFeatures;
+ fontDescription += comma + QString::number(d->features.size());
for (const auto &[tag, value] : std::as_const(d->features).asKeyValueRange())
- sortedFeatures.insert(tag, value);
+ fontDescription += comma + QLatin1StringView{tag.toString()} + u'=' + QString::number(value);
- fontDescription += comma + QString::number(sortedFeatures.size());
- for (const auto &[tag, value] : std::as_const(sortedFeatures).asKeyValueRange())
+ fontDescription += comma + QString::number(d->request.variableAxisValues.size());
+ for (const auto &[tag, value] : std::as_const(d->request.variableAxisValues).asKeyValueRange())
fontDescription += comma + QLatin1StringView{tag.toString()} + u'=' + QString::number(value);
return fontDescription;
@@ -2216,7 +2196,7 @@ size_t qHash(const QFont &font, size_t seed) noexcept
return qHash(QFontPrivate::get(font)->request, seed);
}
-static std::optional<std::pair<QFont::Tag, quint32>> tagAndValueFromString(QStringView view)
+static std::optional<std::pair<QFont::Tag, quint32>> fontFeatureFromString(QStringView view)
{
const int separator = view.indexOf(u'=');
if (separator == -1)
@@ -2234,6 +2214,24 @@ static std::optional<std::pair<QFont::Tag, quint32>> tagAndValueFromString(QStri
return std::make_pair(*tag, value);
}
+static std::optional<std::pair<QFont::Tag, float>> variableAxisFromString(QStringView view)
+{
+ const int separator = view.indexOf(u'=');
+ if (separator == -1)
+ return std::nullopt;
+
+ const std::optional<QFont::Tag> tag = QFont::Tag::fromString(view.sliced(0, separator));
+ if (!tag)
+ return std::nullopt;
+
+ bool valueOk = false;
+ const float value = view.sliced(separator + 1).toFloat(&valueOk);
+ if (!valueOk)
+ return std::nullopt;
+
+ return std::make_pair(*tag, value);
+}
+
/*!
Sets this font to match the description \a descrip. The description
is a comma-separated list of the font attributes, as returned by
@@ -2246,8 +2244,7 @@ bool QFont::fromString(const QString &descrip)
const auto sr = QStringView(descrip).trimmed();
const auto l = sr.split(u',');
const int count = l.size();
- if (!count || (count > 2 && count < 9) || count == 9 ||
- l.first().isEmpty()) {
+ if (!count || (count > 2 && count < 10) || l.first().isEmpty()) {
qWarning("QFont::fromString: Invalid description '%s'",
descrip.isEmpty() ? "(empty)" : descrip.toLatin1().data());
return false;
@@ -2256,14 +2253,8 @@ bool QFont::fromString(const QString &descrip)
setFamily(l[0].toString());
if (count > 1 && l[1].toDouble() > 0.0)
setPointSizeF(l[1].toDouble());
- if (count == 9) {
- setStyleHint((StyleHint) l[2].toInt());
- setWeight(QFont::Weight(l[3].toInt()));
- setItalic(l[4].toInt());
- setUnderline(l[5].toInt());
- setStrikeOut(l[6].toInt());
- setFixedPitch(l[7].toInt());
- } else if (count >= 10) {
+
+ if (count >= 10) {
if (l[2].toInt() > 0)
setPixelSize(l[2].toInt());
setStyleHint((StyleHint) l[3].toInt());
@@ -2275,6 +2266,8 @@ bool QFont::fromString(const QString &descrip)
setUnderline(l[6].toInt());
setStrikeOut(l[7].toInt());
setFixedPitch(l[8].toInt());
+ if (!d->request.fixedPitch) // assume 'false' fixedPitch equals default
+ d->request.ignorePitch = true;
if (count >= 16) {
setCapitalization((Capitalization)l[10].toInt());
setLetterSpacing((SpacingType)l[11].toInt(), l[12].toDouble());
@@ -2291,19 +2284,33 @@ bool QFont::fromString(const QString &descrip)
d->request.styleName.clear();
clearFeatures();
- if (count >= 18) {
- const int featureCount = l[17].toInt();
- if (count >= featureCount + 18) {
- for (int i = 0; i < featureCount; ++i) {
- if (const auto feature = tagAndValueFromString(l[18 + i]))
- setFeature(feature->first, feature->second);
- }
- }
+ clearVariableAxes();
+
+ int position = 17;
+ if (position >= count)
+ return true;
+
+ const int featureCount = l[position++].toInt();
+ if (position + featureCount > count)
+ return true;
+
+ for (int i = 0; i < featureCount; ++i) {
+ if (const auto feature = fontFeatureFromString(l[position++]))
+ setFeature(feature->first, feature->second);
}
- }
- if (count >= 9 && !d->request.fixedPitch) // assume 'false' fixedPitch equals default
- d->request.ignorePitch = true;
+ if (position >= count)
+ return true;
+
+ const int variableAxisCount = l[position++].toInt();
+ if (position + variableAxisCount > count)
+ return true;
+
+ for (int i = 0; i < variableAxisCount; ++i) {
+ if (const auto axis = variableAxisFromString(l[position++]))
+ setVariableAxis(axis->first, axis->second);
+ }
+ }
return true;
}
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 27bc2a6a7cc..76ff29f6e91 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -192,7 +192,7 @@ public:
QFixed letterSpacing;
QFixed wordSpacing;
- QHash<QFont::Tag, quint32> features;
+ QMap<QFont::Tag, quint32> features;
mutable QFontPrivate *scFont;
QFont smallCapsFont() const { return QFont(smallCapsFontPrivate()); }
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 0ad45b1f280..4df55d5b89c 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -402,7 +402,7 @@ bool QFontEngine::processHheaTable() const
const qreal unitsPerEm = emSquareSize().toReal();
// Bail out if values are too large for QFixed
- const auto limitForQFixed = std::numeric_limits<int>::max() / (fontDef.pixelSize * 64);
+ const auto limitForQFixed = qreal(std::numeric_limits<int>::max() >> 6) / fontDef.pixelSize;
if (ascent > limitForQFixed || descent > limitForQFixed || leading > limitForQFixed)
return false;
m_ascent = QFixed::fromReal(ascent * fontDef.pixelSize / unitsPerEm);
@@ -470,7 +470,7 @@ bool QFontEngine::processOS2Table() const
if (typoAscent == 0 && typoDescent == 0)
return false;
// Bail out if values are too large for QFixed
- const auto limitForQFixed = std::numeric_limits<int>::max() / (fontDef.pixelSize * 64);
+ const auto limitForQFixed = qreal(std::numeric_limits<int>::max() >> 6) / fontDef.pixelSize;
if (typoAscent > limitForQFixed || typoDescent > limitForQFixed
|| typoLineGap > limitForQFixed)
return false;
@@ -481,7 +481,7 @@ bool QFontEngine::processOS2Table() const
// Some fonts may have invalid OS/2 data. We detect this and bail out.
if (winAscent == 0 && winDescent == 0)
return false;
- const auto limitForQFixed = std::numeric_limits<int>::max() / (fontDef.pixelSize * 64);
+ const auto limitForQFixed = qreal(std::numeric_limits<int>::max() >> 6) / fontDef.pixelSize;
if (winAscent > limitForQFixed || winDescent > limitForQFixed)
return false;
m_ascent = QFixed::fromReal(winAscent * fontDef.pixelSize / unitsPerEm);
@@ -1059,6 +1059,7 @@ void QFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metr
}
/*!
+ \internal
Returns \c true if the font table idetified by \a tag exists in the font;
returns \c false otherwise.
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 7acc3c5218c..5bd9799ca7d 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -224,7 +224,7 @@ void QRawFont::loadFromData(const QByteArray &fontData,
\since 6.11
*/
-int QRawFont::glyphCount() const
+quint32 QRawFont::glyphCount() const
{
return d->isValid() ? d->fontEngine->glyphCount() : 0;
}
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index f13f04ebe37..a1522aa8048 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -55,7 +55,7 @@ public:
inline bool operator!=(const QRawFont &other) const
{ return !operator==(other); }
- int glyphCount() const;
+ quint32 glyphCount() const;
QString familyName() const;
QString styleName() const;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index eb0f6c3710c..d519cd5a5d3 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1976,7 +1976,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
return;
bool documentPaginated = d->pageSize.isValid() && !d->pageSize.isNull()
- && d->pageSize.height() != INT_MAX;
+ && d->pageSize.height() != qreal(INT_MAX);
// ### set page size to paginated size?
QMarginsF m = printer->pageLayout().margins(QPageLayout::Millimeter);
@@ -2385,6 +2385,11 @@ static QString colorValue(QColor color)
return result;
}
+/*!
+ \class QTextHtmlExporter
+ \inmodule QtGui
+ \internal
+*/
QTextHtmlExporter::QTextHtmlExporter(const QTextDocument *_doc)
: doc(_doc), fragmentMarkers(false)
{
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 227cbae2952..85a74d366ac 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -1006,6 +1006,7 @@ int QTextDocumentPrivate::undoRedo(bool undo)
}
/*!
+ \internal
Appends a custom undo \a item to the undo stack.
*/
void QTextDocumentPrivate::appendUndoItem(QAbstractUndoItem *item)
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 29fda652ef6..41d2d417133 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1414,7 +1414,7 @@ void QTextEngine::shapeText(int item) const
#endif
bool letterSpacingIsAbsolute;
bool shapingEnabled = false;
- QHash<QFont::Tag, quint32> features;
+ QMap<QFont::Tag, quint32> features;
QFixed letterSpacing, wordSpacing;
#ifndef QT_NO_RAWFONT
if (useRawFont) {
@@ -1610,7 +1610,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
int stringBaseIndex, int stringLength, int itemLength,
QFontEngine *fontEngine, QSpan<uint> itemBoundaries,
bool kerningEnabled, bool hasLetterSpacing,
- const QHash<QFont::Tag, quint32> &fontFeatures) const
+ const QMap<QFont::Tag, quint32> &fontFeatures) const
{
uint glyphs_shaped = 0;
@@ -1746,7 +1746,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
// fix up clusters so that the cluster indices will be monotonic
// and thus we never return out-of-order indices
- while (last_cluster++ < cluster && str_pos < item_length)
+ for (uint j = last_cluster; j < cluster && str_pos < item_length; ++j)
log_clusters[str_pos++] = last_glyph_pos;
last_glyph_pos = i + glyphs_shaped;
last_cluster = cluster;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index e513fd598ba..f27463f7728 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -628,7 +628,7 @@ private:
int stringLength, int itemLength, QFontEngine *fontEngine,
QSpan<uint> itemBoundaries, bool kerningEnabled,
bool hasLetterSpacing,
- const QHash<QFont::Tag, quint32> &features) const;
+ const QMap<QFont::Tag, quint32> &features) const;
#endif
int endOfLine(int lineNum);
diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp
index ff8644b5302..337228ff170 100644
--- a/src/gui/text/qtexttable.cpp
+++ b/src/gui/text/qtexttable.cpp
@@ -394,11 +394,9 @@ void QTextTablePrivate::fragmentRemoved(QChar type, uint fragment)
}
/*!
- /fn void QTextTablePrivate::update() const
-
+ \internal
This function is usually called when the table is "dirty".
It seems to update all kind of table information.
-
*/
void QTextTablePrivate::update() const
{
diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp
index 93af1a9600b..0c6d9a31316 100644
--- a/src/gui/text/windows/qwindowsfontdatabase.cpp
+++ b/src/gui/text/windows/qwindowsfontdatabase.cpp
@@ -1113,17 +1113,21 @@ void QWindowsFontDatabase::removeApplicationFonts()
m_eudcFonts.clear();
}
+#if QT_CONFIG(directwrite)
QWindowsFontDatabase::FontHandle::FontHandle(IDWriteFontFace *face, const QString &name)
: fontFace(face), faceName(name)
{
fontFace->AddRef();
}
+#endif // !QT_NO_DIRECTWRITE
QWindowsFontDatabase::FontHandle::~FontHandle()
{
+#if QT_CONFIG(directwrite)
if (fontFace != nullptr)
fontFace->Release();
+#endif // !QT_NO_DIRECTWRITE
}
void QWindowsFontDatabase::releaseHandle(void *handle)
diff --git a/src/gui/text/windows/qwindowsfontdatabase_p.h b/src/gui/text/windows/qwindowsfontdatabase_p.h
index 92e3f04f968..856a5593722 100644
--- a/src/gui/text/windows/qwindowsfontdatabase_p.h
+++ b/src/gui/text/windows/qwindowsfontdatabase_p.h
@@ -78,10 +78,14 @@ public:
struct FontHandle {
FontHandle(const QString &name) : faceName(name) {}
+#if QT_CONFIG(directwrite)
FontHandle(IDWriteFontFace *face, const QString &name);
+#endif // !QT_NO_DIRECTWRITE
~FontHandle();
+#if QT_CONFIG(directwrite)
IDWriteFontFace *fontFace = nullptr;
+#endif // !QT_NO_DIRECTWRITE
QString faceName;
};
diff --git a/src/gui/text/windows/qwindowsfontdatabasebase.cpp b/src/gui/text/windows/qwindowsfontdatabasebase.cpp
index 990f20fa447..055e616dbb2 100644
--- a/src/gui/text/windows/qwindowsfontdatabasebase.cpp
+++ b/src/gui/text/windows/qwindowsfontdatabasebase.cpp
@@ -18,6 +18,8 @@
# include "qwindowsfontenginedirectwrite_p.h"
#endif
+#include <utility> // for std::pair
+
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
@@ -363,7 +365,7 @@ namespace {
inline void addKey(const QByteArray &fontData, const QString &filename)
{
if (!m_fontDatas.contains(fontData.data()))
- m_fontDatas.insert(fontData.data(), qMakePair(fontData, filename));
+ m_fontDatas.insert(fontData.data(), {fontData, filename});
}
HRESULT STDMETHODCALLTYPE GetFilePathLengthFromKey(void const* fontFileReferenceKey,
@@ -433,7 +435,7 @@ namespace {
private:
ULONG m_referenceCount;
- QHash<const void *, QPair<QByteArray, QString> > m_fontDatas;
+ QHash<const void *, std::pair<QByteArray, QString> > m_fontDatas;
};
HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid,
diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp
index 3e10cdad44f..2f0ce3449d9 100644
--- a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp
@@ -1074,7 +1074,7 @@ bool QWindowsFontEngineDirectWrite::traverseColr1(IDWritePaintReader *paintReade
for (int i = 0; i < stopCount; ++i) {
const D2D1_GRADIENT_STOP &stop = stops[i];
QColor color = QColor::fromRgbF(stop.color.r, stop.color.g, stop.color.b, stop.color.a);
- ret.append(qMakePair(stop.position, color));
+ ret.append({stop.position, color});
}
return ret;
diff --git a/src/gui/util/qlayoutpolicy.cpp b/src/gui/util/qlayoutpolicy.cpp
index 4d81a426835..0c0651c1f39 100644
--- a/src/gui/util/qlayoutpolicy.cpp
+++ b/src/gui/util/qlayoutpolicy.cpp
@@ -8,6 +8,11 @@
QT_BEGIN_NAMESPACE
+/*!
+ \class QLayoutPolicy
+ \inmodule QtGui
+ \internal
+*/
void QLayoutPolicy::setControlType(ControlType type)
{
/*