aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/imports/testlib/TestCase.qml6
-rw-r--r--src/imports/window/plugins.qmltypes8
-rw-r--r--src/particles/qquickimageparticle.cpp6
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp6
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp14
-rw-r--r--src/qml/compiler/qv4ssa.cpp1
-rw-r--r--src/qml/jsruntime/qv4engine_p.h3
-rw-r--r--src/qml/jsruntime/qv4managed_p.h9
-rw-r--r--src/qml/jsruntime/qv4object_p.h4
-rw-r--r--src/qml/jsruntime/qv4string.cpp1
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp7
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h2
-rw-r--r--src/qml/types/qqmlconnections.cpp4
-rw-r--r--src/qmltest/quicktestevent.cpp1
-rw-r--r--src/quick/items/qquickanchors.cpp127
-rw-r--r--src/quick/items/qquickanchors_p_p.h19
-rw-r--r--src/quick/items/qquickitem.cpp168
-rw-r--r--src/quick/items/qquickitemchangelistener_p.h4
-rw-r--r--src/quick/items/qquickitemview.cpp4
-rw-r--r--src/quick/items/qquicklistview.cpp20
-rw-r--r--src/quick/items/qquickloader.cpp6
-rw-r--r--src/quick/items/qquickloader_p_p.h2
-rw-r--r--src/quick/items/qquicktextedit.cpp3
-rw-r--r--src/quick/items/qquicktextnode.cpp8
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp7
-rw-r--r--src/quick/items/qquicktextnodeengine_p.h12
-rw-r--r--src/quick/items/qquickview.cpp4
-rw-r--r--src/quick/items/qquickwindow.cpp6
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp57
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h70
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.cpp8
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.h8
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp3
-rw-r--r--src/quick/scenegraph/util/qsgdefaultimagenode.cpp29
-rw-r--r--src/quick/scenegraph/util/qsgdefaultimagenode_p.h6
-rw-r--r--src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp52
-rw-r--r--src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h3
-rw-r--r--src/quick/scenegraph/util/qsgdistancefieldutil.cpp24
-rw-r--r--src/quick/scenegraph/util/qsgdistancefieldutil_p.h4
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.cpp29
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.h6
-rw-r--r--src/quick/scenegraph/util/qsgninepatchnode.cpp52
-rw-r--r--src/quick/scenegraph/util/qsgninepatchnode.h4
-rw-r--r--src/quickwidgets/qquickwidget.cpp4
-rw-r--r--src/quickwidgets/qquickwidget_p.h2
46 files changed, 449 insertions, 376 deletions
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml
index 683200a259..d22ec7c44f 100644
--- a/src/imports/testlib/TestCase.qml
+++ b/src/imports/testlib/TestCase.qml
@@ -221,7 +221,7 @@ Item {
\qmlproperty string TestCase::name
This property defines the name of the test case for result reporting.
- The default is the empty string.
+ The default value is an empty string.
\code
TestCase {
@@ -835,7 +835,7 @@ Item {
\c{QEXPECT_FAIL(tag, message, Abort)} in C++.
If the test is not data-driven, then \a tag must be set to
- the empty string.
+ an empty string.
\sa expectFailContinue()
*/
@@ -861,7 +861,7 @@ Item {
\c{QEXPECT_FAIL(tag, message, Continue)} in C++.
If the test is not data-driven, then \a tag must be set to
- the empty string.
+ an empty string.
\sa expectFail()
*/
diff --git a/src/imports/window/plugins.qmltypes b/src/imports/window/plugins.qmltypes
index 6a8dbfa024..a79bd8c332 100644
--- a/src/imports/window/plugins.qmltypes
+++ b/src/imports/window/plugins.qmltypes
@@ -55,8 +55,12 @@ Module {
name: "QQuickWindow"
defaultProperty: "data"
prototype: "QWindow"
- exports: ["QtQuick.Window/Window 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: [
+ "QtQuick.Window/Window 2.0",
+ "QtQuick.Window/Window 2.1",
+ "QtQuick.Window/Window 2.2"
+ ]
+ exportMetaObjectRevisions: [0, 1, 2]
Enum {
name: "SceneGraphError"
values: {
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index c68153aca8..e6b921792f 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -1292,14 +1292,16 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
// OS X 10.8.3 introduced a bug in the AMD drivers, for at least the 2011 macbook pros,
// causing point sprites who read gl_PointCoord in the frag shader to come out as
// green-red blobs.
- if (perfLevel < Deformable && strstr((char *) glGetString(GL_VENDOR), "ATI")) {
+ const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
+ if (perfLevel < Deformable && glVendor && strstr((char *) glVendor, "ATI")) {
perfLevel = Deformable;
}
#endif
#ifdef Q_OS_LINUX
// Nouveau drivers can potentially freeze a machine entirely when taking the point-sprite path.
- if (perfLevel < Deformable && strstr((const char *) glGetString(GL_VENDOR), "nouveau"))
+ const GLubyte *glVendor = QOpenGLContext::currentContext()->functions()->glGetString(GL_VENDOR);
+ if (perfLevel < Deformable && glVendor && strstr((const char *) glVendor, "nouveau"))
perfLevel = Deformable;
#endif
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
index a318ce23f7..44f79ebea7 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
@@ -3236,11 +3236,11 @@ void QSGD3D12EnginePrivate::DeviceLossTester::killDevice()
void *QSGD3D12EnginePrivate::getResource(QSGRendererInterface::Resource resource) const
{
switch (resource) {
- case QSGRendererInterface::Device:
+ case QSGRendererInterface::DeviceResource:
return device;
- case QSGRendererInterface::CommandQueue:
+ case QSGRendererInterface::CommandQueueResource:
return commandQueue.Get();
- case QSGRendererInterface::CommandList:
+ case QSGRendererInterface::CommandListResource:
return commandList;
default:
break;
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp
index 783caa280f..1f01c440e5 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12publicnodes.cpp
@@ -39,10 +39,6 @@
#include "qsgd3d12publicnodes_p.h"
-// for rebuildGeometry
-#include <private/qsgdefaultninepatchnode_p.h>
-#include <private/qsgdefaultimagenode_p.h>
-
QT_BEGIN_NAMESPACE
QSGD3D12RectangleNode::QSGD3D12RectangleNode()
@@ -138,7 +134,7 @@ void QSGD3D12ImageNode::setRect(const QRectF &r)
return;
m_rect = r;
- QSGDefaultImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
+ QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
markDirty(DirtyGeometry);
}
@@ -153,7 +149,7 @@ void QSGD3D12ImageNode::setSourceRect(const QRectF &r)
return;
m_sourceRect = r;
- QSGDefaultImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
+ QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
markDirty(DirtyGeometry);
}
@@ -170,7 +166,7 @@ void QSGD3D12ImageNode::setTexture(QSGTexture *texture)
delete m_material.texture();
m_material.setTexture(texture);
- QSGDefaultImageNode::rebuildGeometry(&m_geometry, texture, m_rect, m_sourceRect, m_texCoordMode);
+ QSGImageNode::rebuildGeometry(&m_geometry, texture, m_rect, m_sourceRect, m_texCoordMode);
DirtyState dirty = DirtyMaterial;
const bool wasAtlas = m_isAtlasTexture;
@@ -192,7 +188,7 @@ void QSGD3D12ImageNode::setTextureCoordinatesTransform(TextureCoordinatesTransfo
return;
m_texCoordMode = mode;
- QSGDefaultImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
+ QSGImageNode::rebuildGeometry(&m_geometry, texture(), m_rect, m_sourceRect, m_texCoordMode);
markDirty(DirtyMaterial);
}
@@ -247,7 +243,7 @@ void QSGD3D12NinePatchNode::setPadding(qreal left, qreal top, qreal right, qreal
void QSGD3D12NinePatchNode::update()
{
- QSGDefaultNinePatchNode::rebuildGeometry(m_material.texture(), &m_geometry, m_padding, m_bounds, m_devicePixelRatio);
+ QSGNinePatchNode::rebuildGeometry(m_material.texture(), &m_geometry, m_padding, m_bounds, m_devicePixelRatio);
markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
}
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 4fa0cf421b..46de24c264 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -2692,6 +2692,7 @@ void convertConst(Const *c, Type targetType)
case UndefinedType:
c->value = qt_qnan();
c->type = targetType;
+ break;
default:
Q_UNIMPLEMENTED();
Q_ASSERT(!"Unimplemented!");
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 843a6f4d94..a46066bde4 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -131,7 +131,8 @@ public:
Value *jsAlloca(int nValues) {
Value *ptr = jsStackTop;
jsStackTop = ptr + nValues;
- memset(ptr, 0, nValues*sizeof(Value));
+ for (int i = 0; i < nValues; ++i)
+ ptr[i] = Primitive::undefinedValue();
return ptr;
}
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 1fff5a45da..28b255bd9a 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -107,13 +107,20 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
(classname::func == QV4::Managed::func ? 0 : classname::func)
// Q_VTABLE_FUNCTION triggers a bogus tautological-compare warning in GCC6+
-#if defined(Q_CC_GNU) && Q_CC_GNU >= 600
+#if (defined(Q_CC_GNU) && Q_CC_GNU >= 600)
#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \
QT_WARNING_PUSH; \
QT_WARNING_DISABLE_GCC("-Wtautological-compare")
#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF \
;QT_WARNING_POP
+#elif defined(Q_CC_CLANG) && Q_CC_CLANG >= 306
+#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \
+ QT_WARNING_PUSH; \
+ QT_WARNING_DISABLE_CLANG("-Wtautological-compare")
+
+#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF \
+ ;QT_WARNING_POP
#else
#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON
#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 161c7746da..00a004ef5f 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -58,8 +58,6 @@
#include "qv4value_p.h"
#include "qv4internalclass_p.h"
-#include <type_traits>
-
QT_BEGIN_NAMESPACE
@@ -147,7 +145,7 @@ struct ObjectVTable
#define DEFINE_OBJECT_VTABLE_BASE(classname) \
const QV4::ObjectVTable classname::static_vtbl = \
{ \
- DEFINE_MANAGED_VTABLE_INT(classname, (std::is_same<classname::SuperClass, Object>::value) ? Q_NULLPTR : &classname::SuperClass::static_vtbl.vTable), \
+ DEFINE_MANAGED_VTABLE_INT(classname, (std::is_same<classname::SuperClass, Object>::value) ? nullptr : &classname::SuperClass::static_vtbl.vTable), \
call, \
construct, \
get, \
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 3365ffe637..1efd8cb714 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -46,6 +46,7 @@
#include "qv4stringobject_p.h"
#endif
#include <QtCore/QHash>
+#include <QtCore/private/qnumeric_p.h>
using namespace QV4;
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index aac2a42a33..562aa1c88a 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -1100,6 +1100,13 @@ QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QStringRef &n
return qQmlPropertyCacheProperty<const QStringRef &>(engine, obj, name, context, local);
}
+QQmlPropertyData *
+QQmlPropertyCache::property(QJSEngine *engine, QObject *obj, const QLatin1String &name,
+ QQmlContextData *context, QQmlPropertyData &local)
+{
+ return qQmlPropertyCacheProperty<const QLatin1String &>(engine, obj, name, context, local);
+}
+
// these two functions are copied from qmetaobject.cpp
static inline const QMetaObjectPrivate *priv(const uint* data)
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index d34d1bf387..64be1cb206 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -408,6 +408,8 @@ public:
static QQmlPropertyData *property(QJSEngine *, QObject *, const QStringRef &,
QQmlContextData *, QQmlPropertyData &);
+ static QQmlPropertyData *property(QJSEngine *, QObject *, const QLatin1String &,
+ QQmlContextData *, QQmlPropertyData &);
static QQmlPropertyData *property(QJSEngine *, QObject *, const QV4::String *,
QQmlContextData *, QQmlPropertyData &);
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 1e9e0149dc..2aed4d9972 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -165,9 +165,9 @@ private:
void QQmlConnections::setTarget(QObject *obj)
{
Q_D(QQmlConnections);
- d->targetSet = true; // even if setting to 0, it is *set*
- if (d->target == obj)
+ if (d->targetSet && d->target == obj)
return;
+ d->targetSet = true; // even if setting to 0, it is *set*
foreach (QQmlBoundSignal *s, d->boundsignals) {
// It is possible that target is being changed due to one of our signal
// handlers -> use deleteLater().
diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp
index 7a2ec30a5a..26f0521cdf 100644
--- a/src/qmltest/quicktestevent.cpp
+++ b/src/qmltest/quicktestevent.cpp
@@ -183,6 +183,7 @@ namespace QtQuickTest
case MouseMove:
// with move event the button is NoButton, but 'buttons' holds the currently pressed buttons
me = QMouseEvent(QEvent::MouseMove, pos, window->mapToGlobal(pos), Qt::NoButton, button, stateKey);
+ me.setTimestamp(++lastMouseTimestamp);
break;
default:
QTEST_ASSERT(false);
diff --git a/src/quick/items/qquickanchors.cpp b/src/quick/items/qquickanchors.cpp
index a7a4a2b882..4162314cd3 100644
--- a/src/quick/items/qquickanchors.cpp
+++ b/src/quick/items/qquickanchors.cpp
@@ -617,74 +617,75 @@ void QQuickAnchorsPrivate::updateVerticalAnchors()
if (fill || centerIn || !isItemComplete())
return;
- if (updatingVerticalAnchor < 2) {
- ++updatingVerticalAnchor;
- if (usedAnchors & QQuickAnchors::TopAnchor) {
- //Handle stretching
- bool invalid = true;
+ if (Q_UNLIKELY(updatingVerticalAnchor > 1)) {
+ // ### Make this certain :)
+ qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor.");
+ return;
+ }
+
+ ++updatingVerticalAnchor;
+ if (usedAnchors & QQuickAnchors::TopAnchor) {
+ //Handle stretching
+ bool invalid = true;
+ qreal height = 0.0;
+ if (usedAnchors & QQuickAnchors::BottomAnchor) {
+ invalid = calcStretch(topAnchorItem, topAnchorLine,
+ bottomAnchorItem, bottomAnchorLine,
+ topMargin, -bottomMargin, QQuickAnchors::TopAnchor, height);
+ } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
+ invalid = calcStretch(topAnchorItem, topAnchorLine,
+ vCenterAnchorItem, vCenterAnchorLine,
+ topMargin, vCenterOffset, QQuickAnchors::TopAnchor, height);
+ height *= 2;
+ }
+ if (!invalid)
+ setItemHeight(height);
+
+ //Handle top
+ if (topAnchorItem == readParentItem(item)) {
+ setItemY(adjustedPosition(topAnchorItem, topAnchorLine) + topMargin);
+ } else if (readParentItem(topAnchorItem) == readParentItem(item)) {
+ setItemY(position(topAnchorItem, topAnchorLine) + topMargin);
+ }
+ } else if (usedAnchors & QQuickAnchors::BottomAnchor) {
+ //Handle stretching (top + bottom case is handled above)
+ if (usedAnchors & QQuickAnchors::VCenterAnchor) {
qreal height = 0.0;
- if (usedAnchors & QQuickAnchors::BottomAnchor) {
- invalid = calcStretch(topAnchorItem, topAnchorLine,
- bottomAnchorItem, bottomAnchorLine,
- topMargin, -bottomMargin, QQuickAnchors::TopAnchor, height);
- } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
- invalid = calcStretch(topAnchorItem, topAnchorLine,
- vCenterAnchorItem, vCenterAnchorLine,
- topMargin, vCenterOffset, QQuickAnchors::TopAnchor, height);
- height *= 2;
- }
+ bool invalid = calcStretch(vCenterAnchorItem, vCenterAnchorLine,
+ bottomAnchorItem, bottomAnchorLine,
+ vCenterOffset, -bottomMargin, QQuickAnchors::TopAnchor,
+ height);
if (!invalid)
- setItemHeight(height);
-
- //Handle top
- if (topAnchorItem == readParentItem(item)) {
- setItemY(adjustedPosition(topAnchorItem, topAnchorLine) + topMargin);
- } else if (readParentItem(topAnchorItem) == readParentItem(item)) {
- setItemY(position(topAnchorItem, topAnchorLine) + topMargin);
- }
- } else if (usedAnchors & QQuickAnchors::BottomAnchor) {
- //Handle stretching (top + bottom case is handled above)
- if (usedAnchors & QQuickAnchors::VCenterAnchor) {
- qreal height = 0.0;
- bool invalid = calcStretch(vCenterAnchorItem, vCenterAnchorLine,
- bottomAnchorItem, bottomAnchorLine,
- vCenterOffset, -bottomMargin, QQuickAnchors::TopAnchor,
- height);
- if (!invalid)
- setItemHeight(height*2);
- }
+ setItemHeight(height*2);
+ }
- //Handle bottom
- if (bottomAnchorItem == readParentItem(item)) {
- setItemY(adjustedPosition(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
- } else if (readParentItem(bottomAnchorItem) == readParentItem(item)) {
- setItemY(position(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
- }
- } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
- //(stetching handled above)
-
- //Handle vCenter
- if (vCenterAnchorItem == readParentItem(item)) {
- setItemY(adjustedPosition(vCenterAnchorItem, vCenterAnchorLine)
- - vcenter(item) + vCenterOffset);
- } else if (readParentItem(vCenterAnchorItem) == readParentItem(item)) {
- setItemY(position(vCenterAnchorItem, vCenterAnchorLine) - vcenter(item) + vCenterOffset);
- }
- } else if (usedAnchors & QQuickAnchors::BaselineAnchor) {
- //Handle baseline
- if (baselineAnchorItem == readParentItem(item)) {
- setItemY(adjustedPosition(baselineAnchorItem, baselineAnchorLine)
- - readBaselineOffset(item) + baselineOffset);
- } else if (readParentItem(baselineAnchorItem) == readParentItem(item)) {
- setItemY(position(baselineAnchorItem, baselineAnchorLine)
- - readBaselineOffset(item) + baselineOffset);
- }
+ //Handle bottom
+ if (bottomAnchorItem == readParentItem(item)) {
+ setItemY(adjustedPosition(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
+ } else if (readParentItem(bottomAnchorItem) == readParentItem(item)) {
+ setItemY(position(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
+ }
+ } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
+ //(stetching handled above)
+
+ //Handle vCenter
+ if (vCenterAnchorItem == readParentItem(item)) {
+ setItemY(adjustedPosition(vCenterAnchorItem, vCenterAnchorLine)
+ - vcenter(item) + vCenterOffset);
+ } else if (readParentItem(vCenterAnchorItem) == readParentItem(item)) {
+ setItemY(position(vCenterAnchorItem, vCenterAnchorLine) - vcenter(item) + vCenterOffset);
+ }
+ } else if (usedAnchors & QQuickAnchors::BaselineAnchor) {
+ //Handle baseline
+ if (baselineAnchorItem == readParentItem(item)) {
+ setItemY(adjustedPosition(baselineAnchorItem, baselineAnchorLine)
+ - readBaselineOffset(item) + baselineOffset);
+ } else if (readParentItem(baselineAnchorItem) == readParentItem(item)) {
+ setItemY(position(baselineAnchorItem, baselineAnchorLine)
+ - readBaselineOffset(item) + baselineOffset);
}
- --updatingVerticalAnchor;
- } else {
- // ### Make this certain :)
- qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor.");
}
+ --updatingVerticalAnchor;
}
static inline QQuickAnchors::Anchor reverseAnchorLine(QQuickAnchors::Anchor anchorLine)
diff --git a/src/quick/items/qquickanchors_p_p.h b/src/quick/items/qquickanchors_p_p.h
index 221b4ccb40..906f607302 100644
--- a/src/quick/items/qquickanchors_p_p.h
+++ b/src/quick/items/qquickanchors_p_p.h
@@ -113,12 +113,12 @@ public:
, inDestructor(false)
, baselineAnchorLine(QQuickAnchors::InvalidAnchor)
, centerAligned(true)
+ , usedAnchors(QQuickAnchors::InvalidAnchor)
+ , componentComplete(true)
, updatingFill(0)
, updatingCenterIn(0)
, updatingHorizontalAnchor(0)
, updatingVerticalAnchor(0)
- , componentComplete(true)
- , usedAnchors(QQuickAnchors::InvalidAnchor)
{
}
@@ -198,13 +198,16 @@ public:
uint inDestructor : 1;
QQuickAnchors::Anchor baselineAnchorLine : 7;
uint centerAligned : 1;
- uint updatingFill : 2;
- uint updatingCenterIn : 2;
- uint updatingHorizontalAnchor : 2;
- uint updatingVerticalAnchor : 2;
-
- uint componentComplete : 1;
uint usedAnchors : 7; // QQuickAnchors::Anchors
+ uint componentComplete : 1;
+
+ // Instead of using a mostly empty bit field, we can stretch the following fields up to be full
+ // bytes. The advantage is that incrementing/decrementing does not need any combining ands/ors.
+ qint8 updatingFill;
+ qint8 updatingCenterIn;
+ qint8 updatingHorizontalAnchor;
+ qint8 updatingVerticalAnchor;
+
static inline QQuickAnchorsPrivate *get(QQuickAnchors *o) {
return static_cast<QQuickAnchorsPrivate *>(QObjectPrivate::get(o));
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index a05bb1617e..274bfbf6d4 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2308,29 +2308,31 @@ QQuickItem::~QQuickItem()
while (!d->childItems.isEmpty())
d->childItems.constFirst()->setParentItem(0);
- const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
- if (anchor)
- anchor->clearItem(this);
- }
+ if (!d->changeListeners.isEmpty()) {
+ const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
+ if (anchor)
+ anchor->clearItem(this);
+ }
- /*
+ /*
update item anchors that depended on us unless they are our child (and will also be destroyed),
or our sibling, and our parent is also being destroyed.
*/
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
- if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
- anchor->update();
- }
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
+ if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
+ anchor->update();
+ }
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Destroyed)
- change.listener->itemDestroyed(this);
- }
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::Destroyed)
+ change.listener->itemDestroyed(this);
+ }
- d->changeListeners.clear();
+ d->changeListeners.clear();
+ }
/*
Remove any references our transforms have to us, in case they try to
@@ -2601,7 +2603,7 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
if (parentItem) {
QQuickItem *itemAncestor = parentItem;
while (itemAncestor != 0) {
- if (itemAncestor == this) {
+ if (Q_UNLIKELY(itemAncestor == this)) {
qWarning() << "QQuickItem::setParentItem: Parent" << parentItem << "is already part of the subtree of" << this;
return;
}
@@ -3549,10 +3551,12 @@ QQuickAnchors *QQuickItemPrivate::anchors() const
void QQuickItemPrivate::siblingOrderChanged()
{
Q_Q(QQuickItem);
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::SiblingOrder) {
- change.listener->itemSiblingOrderChanged(q);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::SiblingOrder) {
+ change.listener->itemSiblingOrderChanged(q);
+ }
}
}
}
@@ -3654,20 +3658,18 @@ void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
QQuickGeometryChange change;
- QRectF diff(newGeometry.x() - oldGeometry.x(),
- newGeometry.y() - oldGeometry.y(),
- newGeometry.width() - oldGeometry.width(),
- newGeometry.height() - oldGeometry.height());
- change.setXChange(diff.x() != 0);
- change.setYChange(diff.y() != 0);
- change.setWidthChange(diff.width() != 0);
- change.setHeightChange(diff.height() != 0);
-
- const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &listener : listeners) {
- if (listener.types & QQuickItemPrivate::Geometry) {
- if (change.matches(listener.gTypes))
- listener.listener->itemGeometryChanged(this, change, diff);
+ change.setXChange(newGeometry.x() != oldGeometry.x());
+ change.setYChange(newGeometry.y() != oldGeometry.y());
+ change.setWidthChange(newGeometry.width() != oldGeometry.width());
+ change.setHeightChange(newGeometry.height() != oldGeometry.height());
+
+ if (!d->changeListeners.isEmpty()) {
+ const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &listener : listeners) {
+ if (listener.types & QQuickItemPrivate::Geometry) {
+ if (change.matches(listener.gTypes))
+ listener.listener->itemGeometryChanged(this, change, oldGeometry);
+ }
}
}
@@ -4224,12 +4226,14 @@ void QQuickItem::setBaselineOffset(qreal offset)
d->baselineOffset = offset;
- const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Geometry) {
- QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
- if (anchor)
- anchor->updateVerticalAnchors();
+ if (!d->changeListeners.isEmpty()) {
+ const auto listeners = d->changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::Geometry) {
+ QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
+ if (anchor)
+ anchor->updateVerticalAnchors();
+ }
}
}
@@ -5977,20 +5981,24 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
switch (change) {
case QQuickItem::ItemChildAddedChange: {
q->itemChange(change, data);
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Children) {
- change.listener->itemChildAdded(q, data.item);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::Children) {
+ change.listener->itemChildAdded(q, data.item);
+ }
}
}
break;
}
case QQuickItem::ItemChildRemovedChange: {
q->itemChange(change, data);
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Children) {
- change.listener->itemChildRemoved(q, data.item);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::Children) {
+ change.listener->itemChildRemoved(q, data.item);
+ }
}
}
break;
@@ -6000,30 +6008,36 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
break;
case QQuickItem::ItemVisibleHasChanged: {
q->itemChange(change, data);
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Visibility) {
- change.listener->itemVisibilityChanged(q);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::Visibility) {
+ change.listener->itemVisibilityChanged(q);
+ }
}
}
break;
}
case QQuickItem::ItemParentHasChanged: {
q->itemChange(change, data);
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Parent) {
- change.listener->itemParentChanged(q, data.item);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::Parent) {
+ change.listener->itemParentChanged(q, data.item);
+ }
}
}
break;
}
case QQuickItem::ItemOpacityHasChanged: {
q->itemChange(change, data);
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Opacity) {
- change.listener->itemOpacityChanged(q);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::Opacity) {
+ change.listener->itemOpacityChanged(q);
+ }
}
}
break;
@@ -6033,10 +6047,12 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
break;
case QQuickItem::ItemRotationHasChanged: {
q->itemChange(change, data);
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::Rotation) {
- change.listener->itemRotationChanged(q);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::Rotation) {
+ change.listener->itemRotationChanged(q);
+ }
}
}
break;
@@ -6395,10 +6411,12 @@ void QQuickItem::resetWidth()
void QQuickItemPrivate::implicitWidthChanged()
{
Q_Q(QQuickItem);
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::ImplicitWidth) {
- change.listener->itemImplicitWidthChanged(q);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::ImplicitWidth) {
+ change.listener->itemImplicitWidthChanged(q);
+ }
}
}
emit q->implicitWidthChanged();
@@ -6559,10 +6577,12 @@ void QQuickItem::resetHeight()
void QQuickItemPrivate::implicitHeightChanged()
{
Q_Q(QQuickItem);
- const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
- for (const QQuickItemPrivate::ChangeListener &change : listeners) {
- if (change.types & QQuickItemPrivate::ImplicitHeight) {
- change.listener->itemImplicitHeightChanged(q);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::ImplicitHeight) {
+ change.listener->itemImplicitHeightChanged(q);
+ }
}
}
emit q->implicitHeightChanged();
diff --git a/src/quick/items/qquickitemchangelistener_p.h b/src/quick/items/qquickitemchangelistener_p.h
index 19ff73056b..83c69a9330 100644
--- a/src/quick/items/qquickitemchangelistener_p.h
+++ b/src/quick/items/qquickitemchangelistener_p.h
@@ -115,12 +115,14 @@ private:
int kind;
};
+#define QT_QUICK_NEW_GEOMETRY_CHANGED_HANDLING
+
class QQuickItemChangeListener
{
public:
virtual ~QQuickItemChangeListener() {}
- virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF & /* diff */) {}
+ virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF & /* oldGeometry */) {}
virtual void itemSiblingOrderChanged(QQuickItem *) {}
virtual void itemVisibilityChanged(QQuickItem *) {}
virtual void itemOpacityChanged(QQuickItem *) {}
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index d02ed07de0..7d98cc2693 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1207,10 +1207,10 @@ void QQuickItemViewPrivate::showVisibleItems() const
}
void QQuickItemViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change,
- const QRectF &diff)
+ const QRectF &oldGeometry)
{
Q_Q(QQuickItemView);
- QQuickFlickablePrivate::itemGeometryChanged(item, change, diff);
+ QQuickFlickablePrivate::itemGeometryChanged(item, change, oldGeometry);
if (!q->isComponentComplete())
return;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 30625c7ea8..f89a995e76 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -131,7 +131,7 @@ public:
void updateAverage();
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
void fixupPosition() Q_DECL_OVERRIDE;
void fixup(AxisData &data, qreal minExtent, qreal maxExtent) Q_DECL_OVERRIDE;
bool flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
@@ -1401,11 +1401,11 @@ bool QQuickListViewPrivate::hasStickyFooter() const
}
void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change,
- const QRectF &diff)
+ const QRectF &oldGeometry)
{
Q_Q(QQuickListView);
- QQuickItemViewPrivate::itemGeometryChanged(item, change, diff);
+ QQuickItemViewPrivate::itemGeometryChanged(item, change, oldGeometry);
if (!q->isComponentComplete())
return;
@@ -1426,24 +1426,22 @@ void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometry
// position all subsequent items
if (visibleItems.count() && item == visibleItems.constFirst()->item) {
FxListItemSG *listItem = static_cast<FxListItemSG*>(visibleItems.constFirst());
- const QRectF oldGeometry(item->x() - diff.x(),
- item->y() - diff.y(),
- item->width() - diff.width(),
- item->height() - diff.height());
if (listItem->transitionScheduledOrRunning())
return;
if (orient == QQuickListView::Vertical) {
const qreal oldItemEndPosition = verticalLayoutDirection == QQuickItemView::BottomToTop ? -oldGeometry.y() : oldGeometry.y() + oldGeometry.height();
+ const qreal heightDiff = item->height() - oldGeometry.height();
if (verticalLayoutDirection == QQuickListView::TopToBottom && oldItemEndPosition < q->contentY())
- listItem->setPosition(listItem->position() - diff.height(), true);
+ listItem->setPosition(listItem->position() - heightDiff, true);
else if (verticalLayoutDirection == QQuickListView::BottomToTop && oldItemEndPosition > q->contentY())
- listItem->setPosition(listItem->position() + diff.height(), true);
+ listItem->setPosition(listItem->position() + heightDiff, true);
} else {
const qreal oldItemEndPosition = q->effectiveLayoutDirection() == Qt::RightToLeft ? -oldGeometry.x() : oldGeometry.x() + oldGeometry.width();
+ const qreal widthDiff = item->width() - oldGeometry.width();
if (q->effectiveLayoutDirection() == Qt::LeftToRight && oldItemEndPosition < q->contentX())
- listItem->setPosition(listItem->position() - diff.width(), true);
+ listItem->setPosition(listItem->position() - widthDiff, true);
else if (q->effectiveLayoutDirection() == Qt::RightToLeft && oldItemEndPosition > q->contentX())
- listItem->setPosition(listItem->position() + diff.width(), true);
+ listItem->setPosition(listItem->position() + widthDiff, true);
}
}
forceLayoutPolish();
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 9aea9c50df..eeec562e3c 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -65,12 +65,12 @@ QQuickLoaderPrivate::~QQuickLoaderPrivate()
disposeInitialPropertyValues();
}
-void QQuickLoaderPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change
- , const QRectF &diff)
+void QQuickLoaderPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change,
+ const QRectF &oldGeometry)
{
if (resizeItem == item)
_q_updateSize(false);
- QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, diff);
+ QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, oldGeometry);
}
void QQuickLoaderPrivate::itemImplicitWidthChanged(QQuickItem *)
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index a0a9ca0601..9b6267e011 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -84,7 +84,7 @@ public:
QQuickLoaderPrivate();
~QQuickLoaderPrivate();
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
void itemImplicitWidthChanged(QQuickItem *) Q_DECL_OVERRIDE;
void itemImplicitHeightChanged(QQuickItem *) Q_DECL_OVERRIDE;
void clear();
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 4a5358faae..b53bf064b6 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -892,7 +892,7 @@ void QQuickTextEdit::setWrapMode(WrapMode mode)
/*!
\qmlproperty int QtQuick::TextEdit::lineCount
- Returns the total number of lines in the textEdit item.
+ Returns the total number of lines in the TextEdit item.
*/
int QQuickTextEdit::lineCount() const
{
@@ -2350,6 +2350,7 @@ void QQuickTextEdit::moveCursorDelegate()
QRectF cursorRect = cursorRectangle();
d->cursorItem->setX(cursorRect.x());
d->cursorItem->setY(cursorRect.y());
+ d->cursorItem->setHeight(cursorRect.height());
}
void QQuickTextEdit::updateSelection()
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index 8716f98bff..6cfc1d0313 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -160,18 +160,14 @@ void QQuickTextNode::addImage(const QRectF &rect, const QImage &image)
QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext();
QSGInternalImageNode *node = sg->sceneGraphContext()->createInternalImageNode();
QSGTexture *texture = sg->createTexture(image);
- if (m_ownerElement->smooth()) {
+ if (m_ownerElement->smooth())
texture->setFiltering(QSGTexture::Linear);
- texture->setMipmapFiltering(QSGTexture::Linear);
- }
m_textures.append(texture);
node->setTargetRect(rect);
node->setInnerTargetRect(rect);
node->setTexture(texture);
- if (m_ownerElement->smooth()) {
+ if (m_ownerElement->smooth())
node->setFiltering(QSGTexture::Linear);
- node->setMipmapFiltering(QSGTexture::Linear);
- }
appendChildNode(node);
node->update();
}
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index 4631b2e724..538356e679 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -423,7 +423,10 @@ void QQuickTextNodeEngine::addImage(const QRectF &rect, const QImage &image, qre
QRectF searchRect = rect;
if (layoutPosition == QTextFrameFormat::InFlow) {
if (m_currentLineTree.isEmpty()) {
- searchRect.moveTopLeft(m_position + m_currentLine.position() + QPointF(0,1));
+ if (m_currentTextDirection == Qt::RightToLeft)
+ searchRect.moveTopRight(m_position + m_currentLine.rect().topRight() + QPointF(0, 1));
+ else
+ searchRect.moveTopLeft(m_position + m_currentLine.position() + QPointF(0,1));
} else {
const BinaryTreeNode *lastNode = m_currentLineTree.data() + m_currentLineTree.size() - 1;
if (lastNode->glyphRun.isRightToLeft()) {
@@ -952,6 +955,8 @@ void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QText
int preeditPosition = block.isValid() ? block.layout()->preeditAreaPosition() : -1;
#endif
+ setCurrentTextDirection(block.textDirection());
+
QVarLengthArray<QTextLayout::FormatRange> colorChanges;
mergeFormats(block.layout(), &colorChanges);
diff --git a/src/quick/items/qquicktextnodeengine_p.h b/src/quick/items/qquicktextnodeengine_p.h
index 91ed6f4430..18c624513a 100644
--- a/src/quick/items/qquicktextnodeengine_p.h
+++ b/src/quick/items/qquicktextnodeengine_p.h
@@ -144,7 +144,11 @@ public:
int selectionState;
};
- QQuickTextNodeEngine() : m_hasSelection(false), m_hasContents(false) {}
+ QQuickTextNodeEngine()
+ : m_currentTextDirection(Qt::LeftToRight)
+ , m_hasSelection(false)
+ , m_hasContents(false)
+ {}
bool hasContents() const { return m_hasContents; }
void addTextBlock(QTextDocument *, const QTextBlock &, const QPointF &position, const QColor &textColor, const QColor& anchorColor, int selectionStart, int selectionEnd);
@@ -158,6 +162,11 @@ public:
m_currentLine = currentLine;
}
+ void setCurrentTextDirection(Qt::LayoutDirection textDirection)
+ {
+ m_currentTextDirection = textDirection;
+ }
+
void addBorder(const QRectF &rect, qreal border, QTextFrameFormat::BorderStyle borderStyle,
const QBrush &borderBrush);
void addFrameDecorations(QTextDocument *document, QTextFrame *frame);
@@ -247,6 +256,7 @@ private:
QPointF m_position;
QTextLine m_currentLine;
+ Qt::LayoutDirection m_currentTextDirection;
QList<QPair<QRectF, QColor> > m_backgrounds;
QList<QRectF> m_selectionRects;
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index a167f01484..573440ff7f 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -111,14 +111,14 @@ void QQuickViewPrivate::execute()
}
void QQuickViewPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change,
- const QRectF &diff)
+ const QRectF &oldGeometry)
{
Q_Q(QQuickView);
if (resizeItem == root && resizeMode == QQuickView::SizeViewToRootObject) {
// wait for both width and height to be changed
resizetimer.start(0,q);
}
- QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, diff);
+ QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, oldGeometry);
}
/*!
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index dec5b44e2a..722e634fc0 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -3125,10 +3125,12 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
if (itemPriv->paintNode && itemPriv->paintNode->parent() == 0) {
QSGNode *before = qquickitem_before_paintNode(itemPriv);
- if (before)
+ if (before && before->parent()) {
+ Q_ASSERT(before->parent() == itemPriv->childContainerNode());
itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, before);
- else
+ } else {
itemPriv->childContainerNode()->prependChildNode(itemPriv->paintNode);
+ }
}
} else if (itemPriv->paintNode) {
delete itemPriv->paintNode;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index 05d5daa686..d71b0c3e2a 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -215,7 +215,7 @@ QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() c
void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const
{
- if (resource == Painter && window && window->isSceneGraphInitialized())
+ if (resource == PainterResource && window && window->isSceneGraphInitialized())
return static_cast<QSGSoftwareRenderContext *>(QQuickWindowPrivate::get(window)->context)->m_activePainter;
return nullptr;
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 49bbbf0ba8..81aa641e03 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -90,7 +90,7 @@ DECLARE_DEBUG_VAR(noclip)
static QElapsedTimer qsg_renderer_timer;
#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
-#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild; child; child = child->nextSibling)
+#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
static inline int size_of_type(GLenum type)
{
@@ -510,7 +510,7 @@ void Updater::updateRootTransforms(Node *node, Node *root, const QMatrix4x4 &com
while (n != root) {
if (n->type() == QSGNode::TransformNodeType)
m = static_cast<QSGTransformNode *>(n->sgNode)->matrix() * m;
- n = n->parent;
+ n = n->parent();
}
m = combined * m;
@@ -1013,16 +1013,8 @@ void Renderer::nodeWasAdded(QSGNode *node, Node *shadowParent)
Node *snode = m_nodeAllocator.allocate();
snode->sgNode = node;
m_nodes.insert(node, snode);
- if (shadowParent) {
- snode->parent = shadowParent;
- if (shadowParent->lastChild) {
- shadowParent->lastChild->nextSibling = snode;
- shadowParent->lastChild = snode;
- } else {
- shadowParent->firstChild = snode;
- shadowParent->lastChild = snode;
- }
- }
+ if (shadowParent)
+ shadowParent->append(snode);
if (node->type() == QSGNode::GeometryNodeType) {
snode->data = m_elementAllocator.allocate();
@@ -1054,17 +1046,12 @@ void Renderer::nodeWasRemoved(Node *node)
// here, because we delete 'child' (when recursed, down below), so we'd
// have a use-after-free.
{
- Node *child = node->firstChild;
- Node *nextChild = 0;
-
+ Node *child = node->firstChild();
while (child) {
- // Get the next child now before we proceed
- nextChild = child->nextSibling;
-
// Remove (and delete) child
+ node->remove(child);
nodeWasRemoved(child);
-
- child = nextChild;
+ child = node->firstChild();
}
}
@@ -1110,6 +1097,7 @@ void Renderer::nodeWasRemoved(Node *node)
}
Q_ASSERT(m_nodes.contains(node->sgNode));
+
m_nodeAllocator.release(m_nodes.take(node->sgNode));
}
@@ -1120,13 +1108,13 @@ void Renderer::turnNodeIntoBatchRoot(Node *node)
node->isBatchRoot = true;
node->becameBatchRoot = true;
- Node *p = node->parent;
+ Node *p = node->parent();
while (p) {
if (p->type() == QSGNode::ClipNodeType || p->isBatchRoot) {
registerBatchRoot(node, p);
break;
}
- p = p->parent;
+ p = p->parent();
}
SHADOWNODE_TRAVERSE(node)
@@ -1255,33 +1243,18 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
| QSGNode::DirtyForceUpdate);
if (dirtyChain != 0) {
dirtyChain = QSGNode::DirtyState(dirtyChain << 16);
- Node *sn = shadowNode->parent;
+ Node *sn = shadowNode->parent();
while (sn) {
sn->dirtyState |= dirtyChain;
- sn = sn->parent;
+ sn = sn->parent();
}
}
// Delete happens at the very end because it deletes the shadownode.
if (state & QSGNode::DirtyNodeRemoved) {
- Node *parent = shadowNode->parent;
- if (parent) {
- Q_ASSERT(parent->firstChild);
- Q_ASSERT(parent->lastChild);
- shadowNode->parent = 0;
- Node *child = parent->firstChild;
- if (child == shadowNode) {
- parent->firstChild = shadowNode->nextSibling;
- if (parent->lastChild == shadowNode)
- parent->lastChild = 0;
- } else {
- while (child->nextSibling != shadowNode)
- child = child->nextSibling;
- child->nextSibling = shadowNode->nextSibling;
- if (shadowNode == parent->lastChild)
- parent->lastChild = child;
- }
- }
+ Node *parent = shadowNode->parent();
+ if (parent)
+ parent->remove(shadowNode);
nodeWasRemoved(shadowNode);
Q_ASSERT(m_nodes.value(node) == 0);
}
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index d5e94cea3e..322192944b 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -451,11 +451,73 @@ struct Batch
struct Node
{
QSGNode *sgNode;
- Node *parent;
void *data;
- Node *firstChild;
- Node *nextSibling;
- Node *lastChild;
+
+ Node *m_parent;
+ Node *m_child;
+ Node *m_next;
+ Node *m_prev;
+
+ Node *parent() const { return m_parent; }
+
+ void append(Node *child) {
+ Q_ASSERT(child);
+ Q_ASSERT(!hasChild(child));
+ Q_ASSERT(child->m_parent == 0);
+ Q_ASSERT(child->m_next == 0);
+ Q_ASSERT(child->m_prev == 0);
+
+ if (!m_child) {
+ child->m_next = child;
+ child->m_prev = child;
+ m_child = child;
+ } else {
+ m_child->m_prev->m_next = child;
+ child->m_prev = m_child->m_prev;
+ m_child->m_prev = child;
+ child->m_next = m_child;
+ }
+ child->setParent(this);
+ }
+
+ void remove(Node *child) {
+ Q_ASSERT(child);
+ Q_ASSERT(hasChild(child));
+
+ // only child..
+ if (child->m_next == child) {
+ m_child = 0;
+ } else {
+ if (m_child == child)
+ m_child = child->m_next;
+ child->m_next->m_prev = child->m_prev;
+ child->m_prev->m_next = child->m_next;
+ }
+ child->m_next = 0;
+ child->m_prev = 0;
+ child->setParent(0);
+ }
+
+ Node *firstChild() const { return m_child; }
+
+ Node *sibling() const {
+ Q_ASSERT(m_parent);
+ return m_next == m_parent->m_child ? 0 : m_next;
+ }
+
+ void setParent(Node *p) {
+ Q_ASSERT(m_parent == 0 || p == 0);
+ m_parent = p;
+ }
+
+ bool hasChild(Node *child) const {
+ Node *n = m_child;
+ while (n && n != child)
+ n = n->sibling();
+ return n;
+ }
+
+
QSGNode::DirtyState dirtyState;
diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
index fa543aecad..d309044e8f 100644
--- a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp
@@ -81,10 +81,10 @@ QT_BEGIN_NAMESPACE
/*!
\enum QSGRendererInterface::Resource
- \value Device The graphics device, when applicable.
- \value CommandQueue The graphics command queue used by the scenegraph, when applicable.
- \value CommandList The command list or buffer used by the scenegraph, when applicable.
- \value Painter The active QPainter used by the scenegraph, when running with the software backend.
+ \value DeviceResource The graphics device, when applicable.
+ \value CommandQueueResource The graphics command queue used by the scenegraph, when applicable.
+ \value CommandListResource The command list or buffer used by the scenegraph, when applicable.
+ \value PainterResource The active QPainter used by the scenegraph, when running with the software backend.
*/
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.h b/src/quick/scenegraph/coreapi/qsgrendererinterface.h
index a50b362aeb..cf8fcf9015 100644
--- a/src/quick/scenegraph/coreapi/qsgrendererinterface.h
+++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.h
@@ -57,10 +57,10 @@ public:
};
enum Resource {
- Device,
- CommandQueue,
- CommandList,
- Painter
+ DeviceResource,
+ CommandQueueResource,
+ CommandListResource,
+ PainterResource
};
enum ShaderType {
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index 40c3293c7b..b6abb55bd3 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -117,8 +117,9 @@ QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel)
if (image.width() < m_atlas_size_limit && image.height() < m_atlas_size_limit) {
if (!m_atlas)
m_atlas = new Atlas(m_atlas_size);
+ // t may be null for atlas allocation failure
t = m_atlas->create(image);
- if (!hasAlphaChannel && t->hasAlphaChannel())
+ if (t && !hasAlphaChannel && t->hasAlphaChannel())
t->setHasAlphaChannel(false);
}
return t;
diff --git a/src/quick/scenegraph/util/qsgdefaultimagenode.cpp b/src/quick/scenegraph/util/qsgdefaultimagenode.cpp
index 6afe591dca..63773887a0 100644
--- a/src/quick/scenegraph/util/qsgdefaultimagenode.cpp
+++ b/src/quick/scenegraph/util/qsgdefaultimagenode.cpp
@@ -173,33 +173,4 @@ bool QSGDefaultImageNode::ownsTexture() const
return m_ownsTexture;
}
-void QSGDefaultImageNode::rebuildGeometry(QSGGeometry *g,
- QSGTexture *texture,
- const QRectF &rect,
- QRectF sourceRect,
- TextureCoordinatesTransformMode texCoordMode)
-{
- if (!texture)
- return;
-
- if (!sourceRect.width() || !sourceRect.height()) {
- QSize ts = texture->textureSize();
- sourceRect = QRectF(0, 0, ts.width(), ts.height());
- }
-
- // Maybe transform the texture coordinates
- if (texCoordMode.testFlag(QSGImageNode::MirrorHorizontally)) {
- float tmp = sourceRect.left();
- sourceRect.setLeft(sourceRect.right());
- sourceRect.setRight(tmp);
- }
- if (texCoordMode.testFlag(QSGImageNode::MirrorVertically)) {
- float tmp = sourceRect.top();
- sourceRect.setTop(sourceRect.bottom());
- sourceRect.setBottom(tmp);
- }
-
- QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect));
-}
-
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
index eb6c487c18..bb9ebec885 100644
--- a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
+++ b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
@@ -85,12 +85,6 @@ public:
void setOwnsTexture(bool owns) override;
bool ownsTexture() const override;
- static void rebuildGeometry(QSGGeometry *g,
- QSGTexture *texture,
- const QRectF &rect,
- QRectF sourceRect,
- TextureCoordinatesTransformMode texCoordMode);
-
private:
QSGGeometry m_geometry;
QSGOpaqueTextureMaterial m_opaque_material;
diff --git a/src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp b/src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp
index e5a53a3617..6023a9af93 100644
--- a/src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp
+++ b/src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp
@@ -81,56 +81,4 @@ void QSGDefaultNinePatchNode::update()
markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
}
-void QSGDefaultNinePatchNode::rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, const QVector4D &padding,
- const QRectF &bounds, qreal dpr)
-{
- if (padding.x() <= 0 && padding.y() <= 0 && padding.z() <= 0 && padding.w() <= 0) {
- geometry->allocate(4, 0);
- QSGGeometry::updateTexturedRectGeometry(geometry, bounds, texture->normalizedTextureSubRect());
- return;
- }
-
- QRectF tc = texture->normalizedTextureSubRect();
- QSize ts = texture->textureSize();
- ts.setHeight(ts.height() / dpr);
- ts.setWidth(ts.width() / dpr);
-
- qreal invtw = tc.width() / ts.width();
- qreal invth = tc.height() / ts.height();
-
- struct Coord { qreal p; qreal t; };
- Coord cx[4] = { { bounds.left(), tc.left() },
- { bounds.left() + padding.x(), tc.left() + padding.x() * invtw },
- { bounds.right() - padding.z(), tc.right() - padding.z() * invtw },
- { bounds.right(), tc.right() }
- };
- Coord cy[4] = { { bounds.top(), tc.top() },
- { bounds.top() + padding.y(), tc.top() + padding.y() * invth },
- { bounds.bottom() - padding.w(), tc.bottom() - padding.w() * invth },
- { bounds.bottom(), tc.bottom() }
- };
-
- geometry->allocate(16, 28);
- QSGGeometry::TexturedPoint2D *v = geometry->vertexDataAsTexturedPoint2D();
- for (int y = 0; y < 4; ++y) {
- for (int x = 0; x < 4; ++x) {
- v->set(cx[x].p, cy[y].p, cx[x].t, cy[y].t);
- ++v;
- }
- }
-
- quint16 *i = geometry->indexDataAsUShort();
- for (int r = 0; r < 3; ++r) {
- if (r > 0)
- *i++ = 4 * r;
- for (int c = 0; c < 4; ++c) {
- i[0] = 4 * r + c;
- i[1] = 4 * r + c + 4;
- i += 2;
- }
- if (r < 2)
- *i++ = 4 * r + 3 + 4;
- }
-}
-
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h b/src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h
index 675cf48f47..3752a75ac6 100644
--- a/src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h
+++ b/src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h
@@ -70,9 +70,6 @@ public:
void setPadding(qreal left, qreal top, qreal right, qreal bottom) override;
void update() override;
- static void rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, const QVector4D &padding,
- const QRectF &bounds, qreal dpr);
-
private:
QRectF m_bounds;
qreal m_devicePixelRatio;
diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
index 65a6bcd52c..79e43e3820 100644
--- a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
+++ b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
@@ -84,32 +84,12 @@ QSGDistanceFieldGlyphCacheManager::~QSGDistanceFieldGlyphCacheManager()
QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCacheManager::cache(const QRawFont &font)
{
- return m_caches.value(fontKey(font), 0);
+ return m_caches.value(font, 0);
}
void QSGDistanceFieldGlyphCacheManager::insertCache(const QRawFont &font, QSGDistanceFieldGlyphCache *cache)
{
- m_caches.insert(fontKey(font), cache);
-}
-
-QString QSGDistanceFieldGlyphCacheManager::fontKey(const QRawFont &font)
-{
- QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
- if (!fe->faceId().filename.isEmpty()) {
- QByteArray keyName = fe->faceId().filename;
- if (font.style() != QFont::StyleNormal)
- keyName += QByteArray(" I");
- if (font.weight() != QFont::Normal)
- keyName += ' ' + QByteArray::number(font.weight());
- keyName += QByteArray(" DF");
- return QString::fromUtf8(keyName);
- } else {
- return QString::fromLatin1("%1_%2_%3_%4")
- .arg(font.familyName())
- .arg(font.styleName())
- .arg(font.weight())
- .arg(font.style());
- }
+ m_caches.insert(font, cache);
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h b/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
index 354a48a81e..ad366cb4d4 100644
--- a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
+++ b/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
@@ -80,9 +80,7 @@ public:
void setAntialiasingSpreadFunc(AntialiasingSpreadFunc func) { m_antialiasingSpread_func = func; }
private:
- static QString fontKey(const QRawFont &font);
-
- QHash<QString, QSGDistanceFieldGlyphCache *> m_caches;
+ QHash<QRawFont, QSGDistanceFieldGlyphCache *> m_caches;
ThresholdFunc m_threshold_func;
AntialiasingSpreadFunc m_antialiasingSpread_func;
diff --git a/src/quick/scenegraph/util/qsgimagenode.cpp b/src/quick/scenegraph/util/qsgimagenode.cpp
index a78bfc1c66..c03c91d1cb 100644
--- a/src/quick/scenegraph/util/qsgimagenode.cpp
+++ b/src/quick/scenegraph/util/qsgimagenode.cpp
@@ -187,4 +187,33 @@ QT_BEGIN_NAMESPACE
\return \c true if the node takes ownership of the texture; otherwise \c false.
*/
+void QSGImageNode::rebuildGeometry(QSGGeometry *g,
+ QSGTexture *texture,
+ const QRectF &rect,
+ QRectF sourceRect,
+ TextureCoordinatesTransformMode texCoordMode)
+{
+ if (!texture)
+ return;
+
+ if (!sourceRect.width() || !sourceRect.height()) {
+ QSize ts = texture->textureSize();
+ sourceRect = QRectF(0, 0, ts.width(), ts.height());
+ }
+
+ // Maybe transform the texture coordinates
+ if (texCoordMode.testFlag(QSGImageNode::MirrorHorizontally)) {
+ float tmp = sourceRect.left();
+ sourceRect.setLeft(sourceRect.right());
+ sourceRect.setRight(tmp);
+ }
+ if (texCoordMode.testFlag(QSGImageNode::MirrorVertically)) {
+ float tmp = sourceRect.top();
+ sourceRect.setTop(sourceRect.bottom());
+ sourceRect.setBottom(tmp);
+ }
+
+ QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect));
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgimagenode.h b/src/quick/scenegraph/util/qsgimagenode.h
index 7eab42c4e6..d25e732e4b 100644
--- a/src/quick/scenegraph/util/qsgimagenode.h
+++ b/src/quick/scenegraph/util/qsgimagenode.h
@@ -79,6 +79,12 @@ public:
virtual void setOwnsTexture(bool owns) = 0;
virtual bool ownsTexture() const = 0;
+
+ static void rebuildGeometry(QSGGeometry *g,
+ QSGTexture *texture,
+ const QRectF &rect,
+ QRectF sourceRect,
+ TextureCoordinatesTransformMode texCoordMode);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QSGImageNode::TextureCoordinatesTransformMode)
diff --git a/src/quick/scenegraph/util/qsgninepatchnode.cpp b/src/quick/scenegraph/util/qsgninepatchnode.cpp
index 9c167ca76f..33568b5488 100644
--- a/src/quick/scenegraph/util/qsgninepatchnode.cpp
+++ b/src/quick/scenegraph/util/qsgninepatchnode.cpp
@@ -74,4 +74,56 @@ QT_BEGIN_NAMESPACE
\internal
*/
+void QSGNinePatchNode::rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, const QVector4D &padding,
+ const QRectF &bounds, qreal dpr)
+{
+ if (padding.x() <= 0 && padding.y() <= 0 && padding.z() <= 0 && padding.w() <= 0) {
+ geometry->allocate(4, 0);
+ QSGGeometry::updateTexturedRectGeometry(geometry, bounds, texture->normalizedTextureSubRect());
+ return;
+ }
+
+ QRectF tc = texture->normalizedTextureSubRect();
+ QSize ts = texture->textureSize();
+ ts.setHeight(ts.height() / dpr);
+ ts.setWidth(ts.width() / dpr);
+
+ qreal invtw = tc.width() / ts.width();
+ qreal invth = tc.height() / ts.height();
+
+ struct Coord { qreal p; qreal t; };
+ Coord cx[4] = { { bounds.left(), tc.left() },
+ { bounds.left() + padding.x(), tc.left() + padding.x() * invtw },
+ { bounds.right() - padding.z(), tc.right() - padding.z() * invtw },
+ { bounds.right(), tc.right() }
+ };
+ Coord cy[4] = { { bounds.top(), tc.top() },
+ { bounds.top() + padding.y(), tc.top() + padding.y() * invth },
+ { bounds.bottom() - padding.w(), tc.bottom() - padding.w() * invth },
+ { bounds.bottom(), tc.bottom() }
+ };
+
+ geometry->allocate(16, 28);
+ QSGGeometry::TexturedPoint2D *v = geometry->vertexDataAsTexturedPoint2D();
+ for (int y = 0; y < 4; ++y) {
+ for (int x = 0; x < 4; ++x) {
+ v->set(cx[x].p, cy[y].p, cx[x].t, cy[y].t);
+ ++v;
+ }
+ }
+
+ quint16 *i = geometry->indexDataAsUShort();
+ for (int r = 0; r < 3; ++r) {
+ if (r > 0)
+ *i++ = 4 * r;
+ for (int c = 0; c < 4; ++c) {
+ i[0] = 4 * r + c;
+ i[1] = 4 * r + c + 4;
+ i += 2;
+ }
+ if (r < 2)
+ *i++ = 4 * r + 3 + 4;
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgninepatchnode.h b/src/quick/scenegraph/util/qsgninepatchnode.h
index 8677a432ba..8509cbd326 100644
--- a/src/quick/scenegraph/util/qsgninepatchnode.h
+++ b/src/quick/scenegraph/util/qsgninepatchnode.h
@@ -55,6 +55,10 @@ public:
virtual void setDevicePixelRatio(qreal ratio) = 0;
virtual void setPadding(qreal left, qreal top, qreal right, qreal bottom) = 0;
virtual void update() = 0;
+
+ static void rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry,
+ const QVector4D &padding,
+ const QRectF &bounds, qreal dpr);
};
QT_END_NAMESPACE
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index de3692afb0..1d617f5098 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -245,14 +245,14 @@ void QQuickWidgetPrivate::execute()
}
void QQuickWidgetPrivate::itemGeometryChanged(QQuickItem *resizeItem, QQuickGeometryChange change,
- const QRectF &diff)
+ const QRectF &oldGeometry)
{
Q_Q(QQuickWidget);
if (resizeItem == root && resizeMode == QQuickWidget::SizeViewToRootObject) {
// wait for both width and height to be changed
resizetimer.start(0,q);
}
- QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, diff);
+ QQuickItemChangeListener::itemGeometryChanged(resizeItem, change, oldGeometry);
}
void QQuickWidgetPrivate::render(bool needsSync)
diff --git a/src/quickwidgets/qquickwidget_p.h b/src/quickwidgets/qquickwidget_p.h
index 3d64981797..0ba86172e6 100644
--- a/src/quickwidgets/qquickwidget_p.h
+++ b/src/quickwidgets/qquickwidget_p.h
@@ -87,7 +87,7 @@ public:
~QQuickWidgetPrivate();
void execute();
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
void initResize();
void updateSize();
void updatePosition();