aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-07-12 01:01:11 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2019-07-12 16:34:31 +0200
commita6057b46eebc71772d584ea5d318d130e2f40a19 (patch)
tree41867b2b02b7d7078f259bc445c9a60439398a57
parent83f8d886cee0a40ac1ad5e43e597f309f602ad76 (diff)
parentd389fe039203f318a8c9a836dea4c348a1a892a8 (diff)
Merge "Merge remote-tracking branch 'origin/5.13' into dev"
-rw-r--r--src/qml/doc/qtqml.qdocconf1
-rw-r--r--src/qml/qml/qqmlcomponent.cpp12
-rw-r--r--src/qml/qml/qqmltypeloader.cpp6
-rw-r--r--src/qmlmodels/qqmladaptormodel.cpp10
-rw-r--r--src/qmltest/doc/qtqmltest.qdocconf1
-rw-r--r--src/quick/doc/qtquick.qdocconf1
-rw-r--r--src/quick/doc/src/concepts/effects/sprites.qdoc2
-rw-r--r--src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp40
-rw-r--r--src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h9
-rw-r--r--tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp12
-rw-r--r--tests/auto/qml/qqmltypeloader/data/qrcRootPath.qml4
-rw-r--r--tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp8
-rw-r--r--tools/qmlcachegen/qtquickcompiler.prf10
13 files changed, 90 insertions, 26 deletions
diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf
index ba4155c08b..cb9fb575b2 100644
--- a/src/qml/doc/qtqml.qdocconf
+++ b/src/qml/doc/qtqml.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtdeclarative.qdocconf)
project = QtQml
description = Qt QML Reference Documentation
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 59b5cc2691..fefe2bc685 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -569,6 +569,12 @@ void QQmlComponent::setData(const QByteArray &data, const QUrl &url)
{
Q_D(QQmlComponent);
+ if (!d->engine) {
+ // ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check
+ qWarning("QQmlComponent: Must provide an engine before calling setData");
+ return;
+ }
+
d->clear();
d->url = url;
@@ -774,6 +780,12 @@ QObject *QQmlComponent::create(QQmlContext *context)
{
Q_D(QQmlComponent);
+ if (!d->engine) {
+ // ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check
+ qWarning("QQmlComponent: Must provide an engine before calling create");
+ return nullptr;
+ }
+
if (!context)
context = d->engine->rootContext();
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 46207e6b57..4b6c09769a 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -625,7 +625,11 @@ bool QQmlTypeLoader::Blob::addImport(const QV4::CompiledData::Import *import, QL
bool incomplete = false;
- QUrl qmldirUrl = finalUrl().resolved(QUrl(importUri + QLatin1String("/qmldir")));
+ QUrl importUrl(importUri);
+ QString path = importUrl.path();
+ path.append(QLatin1String(path.endsWith(QLatin1Char('/')) ? "qmldir" : "/qmldir"));
+ importUrl.setPath(path);
+ QUrl qmldirUrl = finalUrl().resolved(importUrl);
if (!QQmlImports::isLocal(qmldirUrl)) {
// This is a remote file; the import is currently incomplete
incomplete = true;
diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp
index 0bc67e1aad..48ff4e7d5b 100644
--- a/src/qmlmodels/qqmladaptormodel.cpp
+++ b/src/qmlmodels/qqmladaptormodel.cpp
@@ -161,8 +161,14 @@ public:
signalIndexes.append(propertyId + signalOffset);
}
- for (int i = 0, c = items.count(); i < c; ++i) {
- QQmlDelegateModelItem *item = items.at(i);
+ QVarLengthArray<QQmlGuard<QQmlDelegateModelItem>> guardedItems;
+ for (const auto item : items)
+ guardedItems.append(item);
+
+ for (const auto &item : qAsConst(guardedItems)) {
+ if (item.isNull())
+ continue;
+
const int idx = item->modelIndex();
if (idx >= index && idx < index + count) {
for (int i = 0; i < signalIndexes.count(); ++i)
diff --git a/src/qmltest/doc/qtqmltest.qdocconf b/src/qmltest/doc/qtqmltest.qdocconf
index 9a3e16b64d..25a7ae5f9b 100644
--- a/src/qmltest/doc/qtqmltest.qdocconf
+++ b/src/qmltest/doc/qtqmltest.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtdeclarative.qdocconf)
project = QtQmlTest
description = Qt Quick Test Reference Documentation
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index 6620650d4a..13746b13de 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -1,4 +1,5 @@
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+include($QT_INSTALL_DOCS/config/exampleurl-qtdeclarative.qdocconf)
project = QtQuick
description = Qt Quick Reference Documentation
diff --git a/src/quick/doc/src/concepts/effects/sprites.qdoc b/src/quick/doc/src/concepts/effects/sprites.qdoc
index 004db90eb3..159d9ca8a9 100644
--- a/src/quick/doc/src/concepts/effects/sprites.qdoc
+++ b/src/quick/doc/src/concepts/effects/sprites.qdoc
@@ -144,7 +144,7 @@ these situations, a warning will be output to the console containing the maximum
There are several tools to help turn a set of images into sprite sheets. Here are some examples:
\list
\li Photoshop plugin: \l http://www.johnwordsworth.com/projects/photoshop-sprite-sheet-generator-script
- \li Gimp plugin: \l http://registry.gimp.org/node/20943
+ \li Gimp's SpriteSheet plugin
\li Cmd-line tool: \l http://www.imagemagick.org/script/montage.php
\endlist
diff --git a/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp
index 0f9ca66ad7..b6b6f3b057 100644
--- a/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp
@@ -69,7 +69,8 @@ DEFINE_BOOL_CONFIG_OPTION(qsgPreferFullSizeGlyphCacheTextures, QSG_PREFER_FULLSI
QSGOpenGLDistanceFieldGlyphCache::QSGOpenGLDistanceFieldGlyphCache(QOpenGLContext *c,
const QRawFont &font)
: QSGDistanceFieldGlyphCache(font)
- , m_maxTextureSize(0)
+ , m_maxTextureWidth(0)
+ , m_maxTextureHeight(0)
, m_maxTextureCount(3)
, m_areaAllocator(nullptr)
, m_blitProgram(nullptr)
@@ -113,13 +114,23 @@ void QSGOpenGLDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs
QList<GlyphPosition> glyphPositions;
QVector<glyph_t> glyphsToRender;
+ const int padding = QSG_OPENGL_DISTANCEFIELD_GLYPH_CACHE_PADDING;
+ const qreal scaleFactor = qreal(1) / QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution);
+
+ if (m_maxTextureHeight == 0) {
+ m_funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureWidth);
+
+ // We need to add a buffer to avoid glyphs that overlap the border between two
+ // textures causing the height of the textures to extend beyond the limit.
+ m_maxTextureHeight = m_maxTextureWidth - (qCeil(m_referenceFont.pixelSize() * scaleFactor) + distanceFieldRadius() * 2 + padding * 2);
+ }
+
if (m_areaAllocator == nullptr)
- m_areaAllocator = new QSGAreaAllocator(QSize(maxTextureSize(), m_maxTextureCount * maxTextureSize()));
+ m_areaAllocator = new QSGAreaAllocator(QSize(m_maxTextureWidth, m_maxTextureCount * m_maxTextureHeight));
for (QSet<glyph_t>::const_iterator it = glyphs.constBegin(); it != glyphs.constEnd() ; ++it) {
glyph_t glyphIndex = *it;
- int padding = QSG_OPENGL_DISTANCEFIELD_GLYPH_CACHE_PADDING;
QRectF boundingRect = glyphData(glyphIndex).boundingRect;
int glyphWidth = qCeil(boundingRect.width()) + distanceFieldRadius() * 2;
int glyphHeight = qCeil(boundingRect.height()) + distanceFieldRadius() * 2;
@@ -152,8 +163,8 @@ void QSGOpenGLDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs
continue;
}
- TextureInfo *tex = textureInfo(alloc.y() / maxTextureSize());
- alloc = QRect(alloc.x(), alloc.y() % maxTextureSize(), alloc.width(), alloc.height());
+ TextureInfo *tex = textureInfo(alloc.y() / m_maxTextureHeight);
+ alloc = QRect(alloc.x(), alloc.y() % m_maxTextureHeight, alloc.width(), alloc.height());
tex->allocatedArea |= alloc;
Q_ASSERT(tex->padding == padding || tex->padding < 0);
@@ -541,13 +552,6 @@ bool QSGOpenGLDistanceFieldGlyphCache::createFullSizeTextures() const
return qsgPreferFullSizeGlyphCacheTextures() && glyphCount() > QT_DISTANCEFIELD_HIGHGLYPHCOUNT();
}
-int QSGOpenGLDistanceFieldGlyphCache::maxTextureSize() const
-{
- if (!m_maxTextureSize)
- m_funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
- return m_maxTextureSize;
-}
-
namespace {
struct Qtdf {
// We need these structs to be tightly packed, but some compilers we use do not
@@ -646,7 +650,7 @@ bool QSGOpenGLDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &fon
}
qreal pixelSize = qreal(Qtdf::fetch<quint16>(qtdfTableStart, Qtdf::pixelSize));
- m_maxTextureSize = Qtdf::fetch<quint32>(qtdfTableStart, Qtdf::textureSize);
+ m_maxTextureWidth = m_maxTextureHeight = Qtdf::fetch<quint32>(qtdfTableStart, Qtdf::textureSize);
m_doubleGlyphResolution = Qtdf::fetch<quint8>(qtdfTableStart, Qtdf::flags) == 1;
padding = Qtdf::fetch<quint8>(qtdfTableStart, Qtdf::headerPadding);
@@ -655,7 +659,7 @@ bool QSGOpenGLDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &fon
return false;
}
- if (m_maxTextureSize <= 0) {
+ if (m_maxTextureWidth <= 0) {
qWarning("Invalid texture size in '%s'", qPrintable(font.familyName()));
return false;
}
@@ -663,11 +667,11 @@ bool QSGOpenGLDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &fon
int systemMaxTextureSize;
m_funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &systemMaxTextureSize);
- if (m_maxTextureSize > systemMaxTextureSize) {
+ if (m_maxTextureWidth > systemMaxTextureSize) {
qWarning("System maximum texture size is %d. This is lower than the value in '%s', which is %d",
systemMaxTextureSize,
qPrintable(font.familyName()),
- m_maxTextureSize);
+ m_maxTextureWidth);
}
if (padding != QSG_OPENGL_DISTANCEFIELD_GLYPH_CACHE_PADDING) {
@@ -690,12 +694,12 @@ bool QSGOpenGLDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &fon
return false;
}
- if (m_areaAllocator->size().height() % m_maxTextureSize != 0) {
+ if (m_areaAllocator->size().height() % m_maxTextureHeight != 0) {
qWarning("Area allocator size mismatch in '%s'", qPrintable(font.familyName()));
return false;
}
- textureCount = m_areaAllocator->size().height() / m_maxTextureSize;
+ textureCount = m_areaAllocator->size().height() / m_maxTextureHeight;
m_maxTextureCount = qMax(m_maxTextureCount, textureCount);
const char *textureRecord = allocatorData;
diff --git a/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h
index 99cfe27b9c..66d1b52f86 100644
--- a/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h
@@ -80,7 +80,6 @@ public:
bool useTextureResizeWorkaround() const;
bool useTextureUploadWorkaround() const;
bool createFullSizeTextures() const;
- int maxTextureSize() const;
void setMaxTextureCount(int max) { m_maxTextureCount = max; }
int maxTextureCount() const { return m_maxTextureCount; }
@@ -98,7 +97,7 @@ private:
QDistanceField image;
int padding = -1;
- TextureInfo(const QRect &preallocRect = QRect()) : texture(0), allocatedArea(preallocRect) { }
+ TextureInfo(const QRect &preallocRect = QRect(0, 0, 1, 1)) : texture(0), allocatedArea(preallocRect) { }
};
void createTexture(TextureInfo * texInfo, int width, int height, const void *pixels);
@@ -107,9 +106,10 @@ private:
TextureInfo *textureInfo(int index)
{
+ Q_ASSERT(m_maxTextureWidth > 0 && m_maxTextureHeight > 0);
for (int i = m_textures.count(); i <= index; ++i) {
if (createFullSizeTextures())
- m_textures.append(QRect(0, 0, maxTextureSize(), maxTextureSize()));
+ m_textures.append(QRect(0, 0, m_maxTextureWidth, m_maxTextureWidth));
else
m_textures.append(TextureInfo());
}
@@ -137,7 +137,8 @@ private:
m_blitProgram->link();
}
- mutable int m_maxTextureSize;
+ int m_maxTextureWidth;
+ int m_maxTextureHeight;
int m_maxTextureCount;
bool m_coreProfile;
diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
index 6a3bf53a31..71d3e8fe5f 100644
--- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
+++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
@@ -120,6 +120,7 @@ private slots:
void setNonExistentInitialProperty();
void relativeUrl_data();
void relativeUrl();
+ void setDataNoEngineNoSegfault();
private:
QQmlEngine engine;
@@ -655,6 +656,17 @@ void tst_qqmlcomponent::relativeUrl()
QVERIFY2(!component.isError(), qPrintable(component.errorString()));
}
+void tst_qqmlcomponent::setDataNoEngineNoSegfault()
+{
+ QQmlEngine eng;
+ QQmlComponent comp;
+ QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Must provide an engine before calling setData");
+ comp.setData("import QtQuick 1.0; QtObject { }", QUrl(""));
+ QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Must provide an engine before calling create");
+ auto c = comp.create();
+ QVERIFY(!c);
+}
+
QTEST_MAIN(tst_qqmlcomponent)
#include "tst_qqmlcomponent.moc"
diff --git a/tests/auto/qml/qqmltypeloader/data/qrcRootPath.qml b/tests/auto/qml/qqmltypeloader/data/qrcRootPath.qml
new file mode 100644
index 0000000000..bdbee4eb59
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/qrcRootPath.qml
@@ -0,0 +1,4 @@
+import QtQml 2.12
+import "qrc:/"
+
+QtObject {}
diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
index 0357f121bb..7d69b4a156 100644
--- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
+++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
@@ -58,6 +58,7 @@ private slots:
void qmlSingletonWithinModule();
void multiSingletonModule();
void implicitComponentModule();
+ void qrcRootPathUrl();
};
void tst_QQMLTypeLoader::testLoadComplete()
@@ -505,6 +506,13 @@ void tst_QQMLTypeLoader::implicitComponentModule()
checkCleanCacheLoad(QLatin1String("implicitComponentModule"));
}
+void tst_QQMLTypeLoader::qrcRootPathUrl()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("qrcRootPath.qml"));
+ QCOMPARE(component.status(), QQmlComponent::Ready);
+}
+
QTEST_MAIN(tst_QQMLTypeLoader)
#include "tst_qqmltypeloader.moc"
diff --git a/tools/qmlcachegen/qtquickcompiler.prf b/tools/qmlcachegen/qtquickcompiler.prf
index 2f98aadefe..24cbe7f2e5 100644
--- a/tools/qmlcachegen/qtquickcompiler.prf
+++ b/tools/qmlcachegen/qtquickcompiler.prf
@@ -1,5 +1,15 @@
if(qtc_run|lupdate_run): return()
+!contains(QT, qml) {
+ qt_modules = \
+ $$replace(QT, -private$, _private) \
+ $$replace(QT_PRIVATE, -private$, _private)
+ qt_modules = $$resolve_depends(qt_modules, "QT.", ".depends" ".run_depends")
+ !contains(qt_modules, qml): \
+ error("The qtquickcompiler feature cannot be used without the QML module.")
+ unset(qt_modules)
+}
+
qtPrepareTool(QML_CACHEGEN, qmlcachegen, _FILTER)
qtPrepareTool(QMAKE_RCC, rcc, _DEP)