Merge remote-tracking branch 'origin/5.8' into dev

Conflicts:
	src/qml/jsruntime/qv4object_p.h

Change-Id: Iff4d3aba7710a999b8befdc493cbe959e1ce02f9
This commit is contained in:
Liang Qi 2016-11-23 10:49:37 +01:00
commit 5d4cbf4094
75 changed files with 769 additions and 536 deletions

View File

@ -42,6 +42,72 @@ import QtQuick 2.0
ListModel {
id: stocks
// pre-fetch data for all entries
Component.onCompleted: {
for (var idx = 0; idx < count; ++idx) {
getCloseValue(idx)
}
}
function requestUrl(stockId) {
var endDate = new Date(""); // today
var startDate = new Date()
startDate.setDate(startDate.getDate() - 5);
var request = "http://ichart.finance.yahoo.com/table.csv?";
request += "s=" + stockId;
request += "&g=d";
request += "&a=" + startDate.getMonth();
request += "&b=" + startDate.getDate();
request += "&c=" + startDate.getFullYear();
request += "&d=" + endDate.getMonth();
request += "&e=" + endDate.getDate();
request += "&f=" + endDate.getFullYear();
request += "&g=d";
request += "&ignore=.csv";
return request;
}
function getCloseValue(index) {
var req = requestUrl(get(index).stockId);
if (!req)
return;
var xhr = new XMLHttpRequest;
xhr.open("GET", req, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.LOADING || xhr.readyState === XMLHttpRequest.DONE) {
var records = xhr.responseText.split('\n');
if (records.length > 0 && xhr.status == 200) {
var r = records[1].split(',');
var today = parseFloat(r[4]);
setProperty(index, "value", today.toFixed(2));
r = records[2].split(',');
var yesterday = parseFloat(r[4]);
var change = today - yesterday;
if (change >= 0.0)
setProperty(index, "change", "+" + change.toFixed(2));
else
setProperty(index, "change", change.toFixed(2));
var changePercentage = (change / yesterday) * 100.0;
if (changePercentage >= 0.0)
setProperty(index, "changePercentage", "+" + changePercentage.toFixed(2) + "%");
else
setProperty(index, "changePercentage", changePercentage.toFixed(2) + "%");
} else {
var unknown = "n/a";
set(index, {"value": unknown, "change": unknown, "changePercentage": unknown});
}
}
}
xhr.send()
}
// Uncomment to test invalid entries
// ListElement {name: "The Qt Company"; stockId: "TQTC"; value: "999.0"; change: "0.0"; changePercentage: "0.0"}

View File

@ -64,65 +64,6 @@ Rectangle {
model: StockListModel{}
currentIndex: -1 // Don't pre-select any item
function requestUrl(stockId) {
var endDate = new Date(""); //today
var startDate = new Date()
startDate.setDate(startDate.getDate() - 5);
var request = "http://ichart.finance.yahoo.com/table.csv?";
request += "s=" + stockId;
request += "&g=d";
request += "&a=" + startDate.getMonth();
request += "&b=" + startDate.getDate();
request += "&c=" + startDate.getFullYear();
request += "&d=" + endDate.getMonth();
request += "&e=" + endDate.getDate();
request += "&f=" + endDate.getFullYear();
request += "&g=d";
request += "&ignore=.csv";
return request;
}
function getCloseValue(index) {
var req = requestUrl(model.get(index).stockId);
if (!req)
return;
var xhr = new XMLHttpRequest;
xhr.open("GET", req, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.LOADING || xhr.readyState === XMLHttpRequest.DONE) {
var records = xhr.responseText.split('\n');
if (records.length > 0 && xhr.status == 200) {
var r = records[1].split(',');
var today = parseFloat(r[4]);
model.setProperty(index, "value", today.toFixed(2));
r = records[2].split(',');
var yesterday = parseFloat(r[4]);
var change = today - yesterday;
if (change >= 0.0)
model.setProperty(index, "change", "+" + change.toFixed(2));
else
model.setProperty(index, "change", change.toFixed(2));
var changePercentage = (change / yesterday) * 100.0;
if (changePercentage >= 0.0)
model.setProperty(index, "changePercentage", "+" + changePercentage.toFixed(2) + "%");
else
model.setProperty(index, "changePercentage", changePercentage.toFixed(2) + "%");
} else {
var unknown = "n/a";
model.set(index, {"value": unknown, "change": unknown, "changePercentage": unknown});
}
}
}
xhr.send()
}
onCurrentIndexChanged: {
if (currentItem) {
root.currentStockId = model.get(currentIndex).stockId;
@ -175,7 +116,6 @@ Rectangle {
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: value
Component.onCompleted: view.getCloseValue(index);
}
Text {

View File

@ -66,14 +66,14 @@ Rectangle {
anchors.left: parent.left
anchors.leftMargin: page.width / 32
anchors.topMargin: page.height / 48
spacing: elementSpacing
spacing: page.elementSpacing
//! [0]
Rectangle {
id: green
color: "#80c342"
width: 100 * ratio
height: 100 * ratio
width: 100 * page.ratio
height: 100 * page.ratio
Text {
anchors.left: parent.right
@ -95,8 +95,8 @@ Rectangle {
Rectangle {
id: blue
color: "#14aaff"
width: 100 * ratio
height: 100 * ratio
width: 100 * page.ratio
height: 100 * page.ratio
Text {
anchors.left: parent.right
@ -117,8 +117,8 @@ Rectangle {
Rectangle {
id: purple
color: "#6400aa"
width: 100 * ratio
height: 100 * ratio
width: 100 * page.ratio
height: 100 * page.ratio
Text {
anchors.left: parent.right
@ -140,8 +140,8 @@ Rectangle {
Rectangle {
id: hidingRect
color: "#006325"
width: 100 * ratio
height: 100 * ratio
width: 100 * page.ratio
height: 100 * page.ratio
visible: false
Text {

View File

@ -55,7 +55,7 @@ Item {
interval: 2000
running: true
repeat: true
onTriggered: effectiveOpacity = (effectiveOpacity == 1.0 ? 0.0 : 1.0);
onTriggered: page.effectiveOpacity = (page.effectiveOpacity == 1.0 ? 0.0 : 1.0);
}
Column {
@ -65,7 +65,7 @@ Item {
top: parent.top
topMargin: page.height / 48
}
spacing: elementSpacing
spacing: page.elementSpacing
populate: Transition {
NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce }
@ -77,32 +77,32 @@ Item {
NumberAnimation { properties: "y"; easing.type: Easing.OutBounce }
}
Rectangle { color: "#80c342"; width: bigSize; height: smallSize }
Rectangle { color: "#80c342"; width: page.bigSize; height: page.smallSize }
Rectangle {
id: greenV1
visible: opacity != 0
width: bigSize; height: smallSize
width: page.bigSize; height: page.smallSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#14aaff"; width: bigSize; height: smallSize }
Rectangle { color: "#14aaff"; width: page.bigSize; height: page.smallSize }
Rectangle {
id: greenV2
visible: opacity != 0
width: bigSize; height: smallSize
width: page.bigSize; height: page.smallSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#6400aa"; width: bigSize; height: smallSize }
Rectangle { color: "#80c342"; width: bigSize; height: smallSize }
Rectangle { color: "#6400aa"; width: page.bigSize; height: page.smallSize }
Rectangle { color: "#80c342"; width: page.bigSize; height: page.smallSize }
}
Row {
@ -112,7 +112,7 @@ Item {
bottom: page.bottom
bottomMargin: page.height / 48
}
spacing: elementSpacing
spacing: page.elementSpacing
populate: Transition {
NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce }
@ -124,40 +124,40 @@ Item {
NumberAnimation { properties: "x"; easing.type: Easing.OutBounce }
}
Rectangle { color: "#80c342"; width: smallSize; height: bigSize }
Rectangle { color: "#80c342"; width: page.smallSize; height: page.bigSize }
Rectangle {
id: blueH1
visible: opacity != 0
width: smallSize; height: bigSize
width: page.smallSize; height: page.bigSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#14aaff"; width: smallSize; height: bigSize }
Rectangle { color: "#14aaff"; width: page.smallSize; height: page.bigSize }
Rectangle {
id: greenH2
visible: opacity != 0
width: smallSize; height: bigSize
width: page.smallSize; height: page.bigSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#6400aa"; width: smallSize; height: bigSize }
Rectangle { color: "#80c342"; width: smallSize; height: bigSize }
Rectangle { color: "#6400aa"; width: page.smallSize; height: page.bigSize }
Rectangle { color: "#80c342"; width: page.smallSize; height: page.bigSize }
}
Grid {
anchors.top: parent.top
anchors.topMargin: page.height / 48
anchors.left: flow.left
anchors.left: flowItem.left
columns: 3
spacing: elementSpacing
spacing: page.elementSpacing
populate: Transition {
NumberAnimation { properties: "x,y"; from: 200; duration: 100; easing.type: Easing.OutBounce }
@ -169,55 +169,55 @@ Item {
NumberAnimation { properties: "x,y"; easing.type: Easing.OutBounce }
}
Rectangle { color: "#80c342"; width: smallSize; height: smallSize }
Rectangle { color: "#80c342"; width: page.smallSize; height: page.smallSize }
Rectangle {
id: greenG1
visible: opacity != 0
width: smallSize; height: smallSize
width: page.smallSize; height: page.smallSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#14aaff"; width: smallSize; height: smallSize }
Rectangle { color: "#14aaff"; width: page.smallSize; height: page.smallSize }
Rectangle {
id: greenG2
visible: opacity != 0
width: smallSize; height: smallSize
width: page.smallSize; height:page. smallSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#6400aa"; width: smallSize; height: smallSize }
Rectangle { color: "#6400aa"; width: page.smallSize; height: page.smallSize }
Rectangle {
id: greenG3
visible: opacity != 0
width: smallSize; height: smallSize
width: page.smallSize; height: page.smallSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#80c342"; width: smallSize; height: smallSize }
Rectangle { color: "#14aaff"; width: smallSize; height: smallSize }
Rectangle { color: "#6400aa"; width: smallSize; height: smallSize }
Rectangle { color: "#80c342"; width:page. smallSize; height: page.smallSize }
Rectangle { color: "#14aaff"; width: smallSize; height: page.smallSize }
Rectangle { color: "#6400aa"; width: page.page.smallSize; height: page.smallSize }
}
Flow {
id: flow
id: flowItem
anchors.right: page.right
anchors.rightMargin: page.width / 32
y: 2 * bigSize
width: 1.8 * bigSize
spacing: elementSpacing
y: 2 * page.bigSize
width: 1.8 * page.bigSize
spacing: page.elementSpacing
//! [move]
move: Transition {
@ -237,42 +237,42 @@ Item {
}
//! [populate]
Rectangle { color: "#80c342"; width: smallSize; height: smallSize }
Rectangle { color: "#80c342"; width: page.smallSize; height: page.smallSize }
Rectangle {
id: greenF1
visible: opacity != 0
width: 0.6 * bigSize; height: smallSize
width: 0.6 * page.bigSize; height: page.smallSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#14aaff"; width: 0.3 * bigSize; height: smallSize }
Rectangle { color: "#14aaff"; width: 0.3 * page.bigSize; height: page.smallSize }
Rectangle {
id: greenF2
visible: opacity != 0
width: 0.6 * bigSize; height: smallSize
width: 0.6 * page.bigSize; height: page.smallSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#6400aa"; width: smallSize; height: smallSize }
Rectangle { color: "#6400aa"; width: page.smallSize; height: page.smallSize }
Rectangle {
id: greenF3
visible: opacity != 0
width: 0.4 * bigSize; height: smallSize
width: 0.4 * page.bigSize; height: page.smallSize
color: "#006325"
border.color: "transparent"
Behavior on opacity { NumberAnimation {} }
opacity: effectiveOpacity
opacity: page.effectiveOpacity
}
Rectangle { color: "#80c342"; width: 0.8 * bigSize; height: smallSize }
Rectangle { color: "#80c342"; width: 0.8 * page.bigSize; height: page.smallSize }
}
}

View File

@ -42,12 +42,10 @@
#include <QQuickItem>
#include <QQuickWindow>
#include <QSGRendererInterface>
#include <QFile>
#if QT_CONFIG(d3d12)
#include "vs_shader.hlslh"
#include "ps_shader.hlslh"
D3D12RenderNode::D3D12RenderNode(QQuickItem *item)
: m_item(item)
{
@ -78,7 +76,7 @@ void D3D12RenderNode::releaseResources()
void D3D12RenderNode::init()
{
QSGRendererInterface *rif = m_item->window()->rendererInterface();
m_device = static_cast<ID3D12Device *>(rif->getResource(m_item->window(), QSGRendererInterface::Device));
m_device = static_cast<ID3D12Device *>(rif->getResource(m_item->window(), QSGRendererInterface::DeviceResource));
Q_ASSERT(m_device);
D3D12_ROOT_PARAMETER rootParameter;
@ -111,12 +109,25 @@ void D3D12RenderNode::init()
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
};
QFile f(QStringLiteral(":/scenegraph/rendernode/shader_vert.cso"));
if (!f.open(QIODevice::ReadOnly)) {
qWarning("Failed to open file with vertex shader bytecode");
return;
}
QByteArray vshader_cso = f.readAll();
f.close();
f.setFileName(QStringLiteral(":/scenegraph/rendernode/shader_frag.cso"));
if (!f.open(QIODevice::ReadOnly)) {
qWarning("Failed to open file with fragment shader bytecode");
return;
}
QByteArray fshader_cso = f.readAll();
D3D12_SHADER_BYTECODE vshader;
vshader.pShaderBytecode = g_VS_Simple;
vshader.BytecodeLength = sizeof(g_VS_Simple);
vshader.pShaderBytecode = vshader_cso.constData();
vshader.BytecodeLength = vshader_cso.size();
D3D12_SHADER_BYTECODE pshader;
pshader.pShaderBytecode = g_PS_Simple;
pshader.BytecodeLength = sizeof(g_PS_Simple);
pshader.pShaderBytecode = fshader_cso.constData();
pshader.BytecodeLength = fshader_cso.size();
D3D12_RASTERIZER_DESC rastDesc = {};
rastDesc.FillMode = D3D12_FILL_MODE_SOLID;
@ -235,7 +246,8 @@ void D3D12RenderNode::render(const RenderState *state)
init();
QSGRendererInterface *rif = m_item->window()->rendererInterface();
ID3D12GraphicsCommandList *commandList = static_cast<ID3D12GraphicsCommandList *>(rif->getResource(m_item->window(), QSGRendererInterface::CommandList));
ID3D12GraphicsCommandList *commandList = static_cast<ID3D12GraphicsCommandList *>(
rif->getResource(m_item->window(), QSGRendererInterface::CommandListResource));
Q_ASSERT(commandList);
const int msize = 16 * sizeof(float);

View File

@ -15,24 +15,10 @@ target.path = $$[QT_INSTALL_EXAMPLES]/quick/scenegraph/rendernode
INSTALLS += target
OTHER_FILES += \
main.qml \
shader.hlsl
main.qml
qtConfig(d3d12) {
HEADERS += d3d12renderer.h
SOURCES += d3d12renderer.cpp
LIBS += -ld3d12
VSPS = shader.hlsl
vshader.input = VSPS
vshader.header = vs_shader.hlslh
vshader.entry = VS_Simple
vshader.type = vs_5_0
pshader.input = VSPS
pshader.header = ps_shader.hlslh
pshader.entry = PS_Simple
pshader.type = ps_5_0
HLSL_SHADERS = vshader pshader
load(hlsl_bytecode_header)
}

View File

@ -1,5 +1,7 @@
<RCC>
<qresource prefix="/scenegraph/rendernode">
<file>main.qml</file>
<file>shader_vert.cso</file>
<file>shader_frag.cso</file>
</qresource>
</RCC>

Binary file not shown.

Binary file not shown.

View File

@ -61,7 +61,7 @@ void SoftwareRenderNode::releaseResources()
void SoftwareRenderNode::render(const RenderState *renderState)
{
QSGRendererInterface *rif = m_item->window()->rendererInterface();
QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::Painter));
QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::PainterResource));
Q_ASSERT(p);
p->setTransform(matrix()->toTransform());

View File

@ -44,6 +44,7 @@
#include <QQuickView> //Not using QQmlApplicationEngine because many examples don't have a Window{}
#define DECLARATIVE_EXAMPLE_MAIN(NAME) int main(int argc, char* argv[]) \
{\
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);\
QGuiApplication app(argc,argv);\
app.setOrganizationName("QtProject");\
app.setOrganizationDomain("qt-project.org");\

View File

@ -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()
*/

View File

@ -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: {

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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!");

View File

@ -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;
}

View File

@ -107,11 +107,18 @@ 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

View File

@ -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, \

View File

@ -46,6 +46,7 @@
#include "qv4stringobject_p.h"
#endif
#include <QtCore/QHash>
#include <QtCore/private/qnumeric_p.h>
using namespace QV4;

View File

@ -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); }

View File

@ -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 &);

View File

@ -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().

View File

@ -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);

View File

@ -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;
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;
bool invalid = calcStretch(vCenterAnchorItem, vCenterAnchorLine,
bottomAnchorItem, bottomAnchorLine,
vCenterOffset, -bottomMargin, QQuickAnchors::TopAnchor,
height);
if (!invalid)
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);
}
}
--updatingVerticalAnchor;
} else {
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;
bool invalid = calcStretch(vCenterAnchorItem, vCenterAnchorLine,
bottomAnchorItem, bottomAnchorLine,
vCenterOffset, -bottomMargin, QQuickAnchors::TopAnchor,
height);
if (!invalid)
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);
}
}
--updatingVerticalAnchor;
}
static inline QQuickAnchors::Anchor reverseAnchorLine(QQuickAnchors::Anchor anchorLine)

View File

@ -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));

View File

@ -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);
change.setXChange(newGeometry.x() != oldGeometry.x());
change.setYChange(newGeometry.y() != oldGeometry.y());
change.setWidthChange(newGeometry.width() != oldGeometry.width());
change.setHeightChange(newGeometry.height() != oldGeometry.height());
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);
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();

View File

@ -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 *) {}

View File

@ -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;

View File

@ -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();

View File

@ -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 *)

View File

@ -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();

View File

@ -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()

View File

@ -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();
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
/*!

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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.
*/
/*!

View File

@ -57,10 +57,10 @@ public:
};
enum Resource {
Device,
CommandQueue,
CommandList,
Painter
DeviceResource,
CommandQueueResource,
CommandListResource,
PainterResource
};
enum ShaderType {

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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();

View File

@ -13,14 +13,3 @@
);
%deprecatedheaders = (
);
# Module dependencies.
# Every module that is required to build this module should have one entry.
# Each of the module version specifiers can take one of the following values:
# - A specific Git revision.
# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch)
# - an empty string to use the same branch under test (dependencies will become "refs/heads/master" if we are in the master branch)
#
%dependencies = (
"qtbase" => "",
"qtxmlpatterns" => "",
);

View File

@ -1372,6 +1372,33 @@ void tst_QJSValue::hasProperty_changePrototype()
QVERIFY(obj.hasOwnProperty("foo"));
}
void tst_QJSValue::hasProperty_QTBUG56830_data()
{
QTest::addColumn<QString>("key");
QTest::addColumn<QString>("lookup");
QTest::newRow("bugreport-1") << QStringLiteral("240000000000") << QStringLiteral("3776798720");
QTest::newRow("bugreport-2") << QStringLiteral("240000000001") << QStringLiteral("3776798721");
QTest::newRow("biggest-ok-before-bug") << QStringLiteral("238609294221") << QStringLiteral("2386092941");
QTest::newRow("smallest-bugged") << QStringLiteral("238609294222") << QStringLiteral("2386092942");
QTest::newRow("biggest-bugged") << QStringLiteral("249108103166") << QStringLiteral("12884901886");
QTest::newRow("smallest-ok-after-bug") << QStringLiteral("249108103167") << QStringLiteral("12884901887");
}
void tst_QJSValue::hasProperty_QTBUG56830()
{
QFETCH(QString, key);
QFETCH(QString, lookup);
QJSEngine eng;
const QJSValue value(42);
QJSValue obj = eng.newObject();
obj.setProperty(key, value);
QVERIFY(obj.hasProperty(key));
QVERIFY(!obj.hasProperty(lookup));
}
void tst_QJSValue::deleteProperty_basic()
{
QJSEngine eng;

View File

@ -92,6 +92,8 @@ private slots:
void hasProperty_basic();
void hasProperty_globalObject();
void hasProperty_changePrototype();
void hasProperty_QTBUG56830_data();
void hasProperty_QTBUG56830();
void deleteProperty_basic();
void deleteProperty_globalObject();

View File

@ -0,0 +1,9 @@
import QtQuick 2.0
Item {
width: 50
property bool tested: false
Connections { onWidthChanged: tested = true }
}

View File

@ -52,6 +52,7 @@ private slots:
void rewriteErrors();
void singletonTypeTarget();
void enableDisable_QTBUG_36350();
void clearImplicitTarget();
private:
QQmlEngine engine;
@ -352,6 +353,32 @@ void tst_qqmlconnections::enableDisable_QTBUG_36350()
delete item;
}
//QTBUG-56499
void tst_qqmlconnections::clearImplicitTarget()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("test-connection-implicit.qml"));
QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
QVERIFY(item != 0);
// normal case: fire Connections
item->setWidth(100.);
QCOMPARE(item->property("tested").toBool(), true);
item->setProperty("tested", false);
// clear the implicit target
QQmlConnections *connections = item->findChild<QQmlConnections*>();
QVERIFY(connections);
connections->setTarget(0);
// target cleared: no longer fire Connections
item->setWidth(150.);
QCOMPARE(item->property("tested").toBool(), false);
delete item;
}
QTEST_MAIN(tst_qqmlconnections)
#include "tst_qqmlconnections.moc"

View File

@ -2726,9 +2726,9 @@ struct TestListener : public QQuickItemChangeListener
{
TestListener(bool remove = false) : remove(remove) { }
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &diff) override
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange, const QRectF &oldGeometry) override
{
record(item, QQuickItemPrivate::Geometry, diff);
record(item, QQuickItemPrivate::Geometry, oldGeometry);
}
void itemSiblingOrderChanged(QQuickItem *item) override
{
@ -2810,20 +2810,20 @@ void tst_QQuickItem::changeListener()
item->setImplicitWidth(10);
QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitWidth), 1);
QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 1);
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,0)));
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,0)));
item->setImplicitHeight(20);
QCOMPARE(itemListener.count(QQuickItemPrivate::ImplicitHeight), 1);
QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 2);
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,20)));
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,0)));
item->setWidth(item->width() + 30);
QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 3);
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,30,0)));
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,10,20)));
item->setHeight(item->height() + 40);
QCOMPARE(itemListener.count(QQuickItemPrivate::Geometry), 4);
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,0,40)));
QCOMPARE(itemListener.value(QQuickItemPrivate::Geometry), QVariant(QRectF(0,0,40,20)));
item->setOpacity(0.5);
QCOMPARE(itemListener.count(QQuickItemPrivate::Opacity), 1);

View File

@ -0,0 +1,20 @@
import QtQuick 2.0
Rectangle {
width: 300
height: 300
color: "white"
TextEdit {
objectName: "textEditObject"
width: 300
height: 300
text: "<span style=\"font-size:20pt;\">Blah</span><br>blah"
textFormat: TextEdit.RichText
cursorDelegate: Rectangle {
objectName: "cursorInstance"
color: "red"
width: 2
}
}
}

View File

@ -140,6 +140,7 @@ private slots:
void cursorVisible();
void delegateLoading_data();
void delegateLoading();
void cursorDelegateHeight();
void navigation();
void readOnly();
#ifndef QT_NO_CLIPBOARD
@ -2848,6 +2849,43 @@ void tst_qquicktextedit::delegateLoading()
//QVERIFY(!delegate);
}
void tst_qquicktextedit::cursorDelegateHeight()
{
QQuickView view(testFileUrl("cursorHeight.qml"));
view.show();
view.requestActivate();
QTest::qWaitForWindowActive(&view);
QQuickTextEdit *textEditObject = view.rootObject()->findChild<QQuickTextEdit*>("textEditObject");
QVERIFY(textEditObject);
// Delegate creation is deferred until focus in or cursor visibility is forced.
QVERIFY(!textEditObject->findChild<QQuickItem*>("cursorInstance"));
QVERIFY(!textEditObject->isCursorVisible());
// Test that the delegate gets created.
textEditObject->setFocus(true);
QVERIFY(textEditObject->isCursorVisible());
QQuickItem* delegateObject = textEditObject->findChild<QQuickItem*>("cursorInstance");
QVERIFY(delegateObject);
const int largerHeight = textEditObject->cursorRectangle().height();
textEditObject->setCursorPosition(0);
QCOMPARE(delegateObject->x(), textEditObject->cursorRectangle().x());
QCOMPARE(delegateObject->y(), textEditObject->cursorRectangle().y());
QCOMPARE(delegateObject->height(), textEditObject->cursorRectangle().height());
// Move the cursor to the next line, which has a smaller font.
textEditObject->setCursorPosition(5);
QCOMPARE(delegateObject->x(), textEditObject->cursorRectangle().x());
QCOMPARE(delegateObject->y(), textEditObject->cursorRectangle().y());
QVERIFY(textEditObject->cursorRectangle().height() < largerHeight);
QCOMPARE(delegateObject->height(), textEditObject->cursorRectangle().height());
// Test that the delegate gets deleted
textEditObject->setCursorDelegate(0);
QVERIFY(!textEditObject->findChild<QQuickItem*>("cursorInstance"));
}
/*
TextEdit element should only handle left/right keys until the cursor reaches
the extent of the text, then they should ignore the keys.

View File

@ -0,0 +1,14 @@
import QtQuick 2.0
Item {
width: 320
height: 480
Text {
anchors.centerIn: parent
font.family: "Arial"
font.pixelSize: 16
textFormat: Text.RichText
text: "<img width=16 height=16 src=\"data/logo.png\" />This image is in the start of the text"
}
}

View File

@ -0,0 +1,14 @@
import QtQuick 2.0
Item {
width: 320
height: 480
Text {
anchors.centerIn: parent
font.family: "Arial"
font.pixelSize: 16
textFormat: Text.RichText
text: "<img width=16 height=16 src=\"data/logo.png\" />هو أمّا حكومة"
}
}

View File

@ -453,6 +453,7 @@ int main(int argc, char *argv[])
app->setApplicationName("Qml Runtime");
app->setOrganizationName("QtProject");
app->setOrganizationDomain("qt-project.org");
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
qmlRegisterType<Config>("QmlRuntime.Config", 1, 0, "Configuration");
qmlRegisterType<PartialScene>("QmlRuntime.Config", 1, 0, "PartialScene");

View File

@ -33,6 +33,7 @@
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
MainWindow mainWindow;
mainWindow.show();

View File

@ -485,6 +485,7 @@ QVariantList findQmlImportsRecursively(const QStringList &qmlDirs, const QString
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
QStringList args = app.arguments();
const QString appName = QFileInfo(app.applicationFilePath()).baseName();
if (args.size() < 2) {
@ -529,7 +530,12 @@ int main(int argc, char *argv[])
if (arg.startsWith(QLatin1Char('-')) && arg != QLatin1String("-"))
break;
++i;
*argReceiver += arg;
if (!QFile::exists(arg)) {
std::cerr << "No such file or directory: \"" << qPrintable(arg) << "\"\n";
return 1;
} else {
*argReceiver += arg;
}
}
}

View File

@ -135,6 +135,7 @@ static void showException(QV4::ExecutionContext *ctx, const QV4::Value &exceptio
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
QStringList args = app.arguments();
args.removeFirst();

View File

@ -533,6 +533,7 @@ static void usage(bool showHelp = false)
int runQmlmin(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
const QStringList args = app.arguments();

View File

@ -987,6 +987,7 @@ int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
QGuiApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
const QStringList args = app.arguments();
const QString appName = QFileInfo(app.applicationFilePath()).baseName();
if (args.size() < 2) {

View File

@ -467,6 +467,7 @@ int main(int argc, char ** argv)
app.setApplicationName("QtQmlViewer");
app.setOrganizationName("QtProject");
app.setOrganizationDomain("qt-project.org");
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
const QStringList arguments = QCoreApplication::arguments();
for (int i = 1, size = arguments.size(); i < size; ++i) {

View File

@ -205,6 +205,7 @@ void usage(const char *name)
int main(int argc, char ** argv)
{
QGuiApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
qmlRegisterType<Timer>("QmlTime", 1, 0, "Timer");