diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-07-12 01:01:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2019-07-12 16:34:31 +0200 |
commit | a6057b46eebc71772d584ea5d318d130e2f40a19 (patch) | |
tree | 41867b2b02b7d7078f259bc445c9a60439398a57 | |
parent | 83f8d886cee0a40ac1ad5e43e597f309f602ad76 (diff) | |
parent | d389fe039203f318a8c9a836dea4c348a1a892a8 (diff) |
Merge "Merge remote-tracking branch 'origin/5.13' into dev"
-rw-r--r-- | src/qml/doc/qtqml.qdocconf | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 6 | ||||
-rw-r--r-- | src/qmlmodels/qqmladaptormodel.cpp | 10 | ||||
-rw-r--r-- | src/qmltest/doc/qtqmltest.qdocconf | 1 | ||||
-rw-r--r-- | src/quick/doc/qtquick.qdocconf | 1 | ||||
-rw-r--r-- | src/quick/doc/src/concepts/effects/sprites.qdoc | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgopengldistancefieldglyphcache.cpp | 40 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgopengldistancefieldglyphcache_p.h | 9 | ||||
-rw-r--r-- | tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp | 12 | ||||
-rw-r--r-- | tests/auto/qml/qqmltypeloader/data/qrcRootPath.qml | 4 | ||||
-rw-r--r-- | tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp | 8 | ||||
-rw-r--r-- | tools/qmlcachegen/qtquickcompiler.prf | 10 |
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) |