From add3c14a28c80f6807164d689b921efcbaeff5bc Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 3 Apr 2015 18:26:04 +0300 Subject: [PATCH 02/25] QAbstractSocket: fix some 64-bit issues in debug code Change-Id: I78b307b2841353f84b033a815035436ec3eef3b0 Reviewed-by: Thiago Macieira --- src/network/socket/qabstractsocket.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 18dbed5a16..f5dcdcba1c 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1265,8 +1265,8 @@ bool QAbstractSocketPrivate::readFromSocket() bytesToRead = readBufferMaxSize - buffer.size(); #if defined(QABSTRACTSOCKET_DEBUG) - qDebug("QAbstractSocketPrivate::readFromSocket() about to read %d bytes", - int(bytesToRead)); + qDebug("QAbstractSocketPrivate::readFromSocket() about to read %lld bytes", + bytesToRead); #endif // Read from the socket, store data in the read buffer. @@ -1277,10 +1277,10 @@ bool QAbstractSocketPrivate::readFromSocket() buffer.chop(bytesToRead); return true; } - buffer.chop(int(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes))); + buffer.chop(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes)); #if defined(QABSTRACTSOCKET_DEBUG) - qDebug("QAbstractSocketPrivate::readFromSocket() got %d bytes, buffer size = %d", - int(readBytes), buffer.size()); + qDebug("QAbstractSocketPrivate::readFromSocket() got %lld bytes, buffer size = %lld", + readBytes, buffer.size()); #endif if (!socketEngine->isValid()) { @@ -1726,7 +1726,7 @@ qint64 QAbstractSocket::bytesAvailable() const available += d->socketEngine->bytesAvailable(); #if defined(QABSTRACTSOCKET_DEBUG) - qDebug("QAbstractSocket::bytesAvailable() == %llu", available); + qDebug("QAbstractSocket::bytesAvailable() == %lld", available); #endif return available; } @@ -1805,8 +1805,8 @@ bool QAbstractSocket::canReadLine() const { bool hasLine = d_func()->buffer.canReadLine(); #if defined (QABSTRACTSOCKET_DEBUG) - qDebug("QAbstractSocket::canReadLine() == %s, buffer size = %d, size = %d", hasLine ? "true" : "false", - d_func()->buffer.size(), d_func()->buffer.size()); + qDebug("QAbstractSocket::canReadLine() == %s, buffer size = %lld, size = %lld", + hasLine ? "true" : "false", d_func()->buffer.size(), d_func()->buffer.size()); #endif return hasLine || QIODevice::canReadLine(); } From 9b134f4e72c21ad9c9a4979248658089fd525d0a Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 1 Apr 2015 12:45:41 +0200 Subject: [PATCH 03/25] Add Q_UNUSED for parameter (OS X) Ifdefs exclude the code on OS X, but there is still unused parameter and annoying compiler (either warning or error, depending on ...). Change-Id: I913c25b4f96ebe275a6b1d15873bccf4aebe9e7a Reviewed-by: Gabriel de Dietrich --- src/widgets/widgets/qtabbar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 02967e33c1..b2973bd8b3 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -2036,6 +2036,8 @@ void QTabBar::wheelEvent(QWheelEvent *event) int offset = event->delta() > 0 ? -1 : 1; d->setCurrentNextEnabledIndex(offset); QWidget::wheelEvent(event); +#else + Q_UNUSED(event) #endif } #endif //QT_NO_WHEELEVENT From b9290065131ae60c9b92c850f0bb6121fbb618c1 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 7 Apr 2015 10:27:08 +0200 Subject: [PATCH 05/25] qdoc: Use the title instead of plain name when listing groups When listing group nodes, for example, with \annotatedlist command, QDoc created a link with the plain name (the string that was passed to \group command as parameter) as the link text. This change makes QDoc use the group \title, if one exists. Change-Id: I30b7f9eefc60c12f67b1e579bbc4c5cebe84474b Task-number: QTBUG-45420 Reviewed-by: Martin Smith --- src/tools/qdoc/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index 8e094f38c4..24c64538c3 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -149,7 +149,7 @@ QString Node::plainFullName(const Node* relative) const */ QString Node::fullName(const Node* relative) const { - if (isDocumentNode()) + if ((isDocumentNode() || isGroup()) && !title().isEmpty()) return title(); return plainFullName(relative); } From 32849f4997e13f540a6c99c9a644239e19839d73 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 16 Mar 2015 14:15:27 +0100 Subject: [PATCH 07/25] qmake: Rework dll deployment QT_INSTALL_LIBS is not the right place to check for Qt dlls, as they cannot be found there in a non-developer build. In order to be able to find the dlls and make adding dll locations easier for the user, QMAKE_DLLS_PATHS was added. On Windows, the variable points to Qt's bin directory by default. Task-number: QTBUG-44960 Change-Id: Ie4e5beeaadee798a055599387e842d7c0502c27a Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt.prf | 6 +-- qmake/generators/win32/msvc_vcproj.cpp | 52 ++++++++++++++++---------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index b1fc248ea0..264641b5b3 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -4,10 +4,8 @@ CONFIG *= thread win32 { contains(QT_CONFIG, shared) { # this variable is read by qmake in qmake/generators/win32/msvc_vcproj.cpp - # function VcprojGenerator::initDeploymentTool(), which contains some hardcoded - # library names (the ones that were static in Qt 4) - # it probably doesn't work anymore and should not be in this file - QMAKE_QT_DLL = 1 + # function VcprojGenerator::initDeploymentTool() + QMAKE_DLL_PATHS += $$[QT_INSTALL_BINS/get] } } CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 4822bcf22a..3222030018 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1267,31 +1267,43 @@ void VcprojGenerator::initDeploymentTool() if (targetPath.endsWith("/") || targetPath.endsWith("\\")) targetPath.chop(1); } - + ProStringList dllPaths = project->values("QMAKE_DLL_PATHS"); // Only deploy Qt libs for shared build - if (!project->values("QMAKE_QT_DLL").isEmpty()) { + if (!dllPaths.isEmpty()) { // FIXME: This code should actually resolve the libraries from all Qt modules. - const QString &qtdir = project->propertyValue(ProKey("QT_INSTALL_LIBS/get")).toQString(); ProStringList arg = project->values("QMAKE_LIBS") + project->values("QMAKE_LIBS_PRIVATE"); for (ProStringList::ConstIterator it = arg.constBegin(); it != arg.constEnd(); ++it) { - if (it->contains(qtdir)) { - QString dllName = (*it).toQString(); + QString dllName = (*it).toQString(); + dllName.replace(QLatin1Char('\\'), QLatin1Char('/')); + // LIBPATH isn't relevant for deployment + if (dllName.startsWith(QLatin1String("/LIBPATH:"))) + continue; + // We want to deploy .dlls not .libs + if (dllName.endsWith(QLatin1String(".lib"))) + dllName.replace(dllName.length() - 3, 3, QLatin1String("dll")); + // Use only the file name and check in Qt's install path and LIBPATHs to check for existence + dllName.remove(0, dllName.lastIndexOf(QLatin1Char('/')) + 1); + QFileInfo info; + foreach (const ProString &dllPath, dllPaths) { + QString absoluteDllFilePath = dllPath.toQString(); + if (!absoluteDllFilePath.endsWith(QLatin1Char('/'))) + absoluteDllFilePath += QLatin1Char('/'); + absoluteDllFilePath += dllName; + info = QFileInfo(absoluteDllFilePath); + if (info.exists()) + break; + } - if (dllName.contains(QLatin1String("QAxContainer")) - || dllName.contains(QLatin1String("qtmain")) - || dllName.contains(QLatin1String("QtUiTools"))) - continue; - dllName.replace(QLatin1String(".lib") , QLatin1String(".dll")); - QFileInfo info(dllName); - if (conf.WinRT) { - QString absoluteFilePath(QDir::toNativeSeparators(info.absoluteFilePath())); - vcProject.DeploymentFiles.addFile(absoluteFilePath); - } else { - conf.deployment.AdditionalFiles += info.fileName() - + "|" + QDir::toNativeSeparators(info.absolutePath()) - + "|" + targetPath - + "|0;"; - } + if (!info.exists()) + continue; + if (conf.WinRT) { + QString absoluteFilePath(QDir::toNativeSeparators(info.absoluteFilePath())); + vcProject.DeploymentFiles.addFile(absoluteFilePath); + } else { + conf.deployment.AdditionalFiles += info.fileName() + + "|" + QDir::toNativeSeparators(info.absolutePath()) + + "|" + targetPath + + "|0;"; } } } From 51028d147289c2e388684ad195f5ec2daa2e7b3e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 5 Apr 2015 19:49:05 +0200 Subject: [PATCH 08/25] QQueue: unhide QList::swap(int, int) Task-number: QTBUG-34197 Change-Id: I0b405ab0fabff8852b2705d651848fbff74fc4c2 Reviewed-by: Kai Koehne --- src/corelib/tools/qqueue.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/corelib/tools/qqueue.h b/src/corelib/tools/qqueue.h index ae07c7d026..9d5bda1210 100644 --- a/src/corelib/tools/qqueue.h +++ b/src/corelib/tools/qqueue.h @@ -46,6 +46,11 @@ public: inline QQueue() {} inline ~QQueue() {} inline void swap(QQueue &other) { QList::swap(other); } // prevent QList<->QQueue swaps +#ifndef Q_QDOC + // bring in QList::swap(int, int). We cannot say using QList::swap, + // because we don't want to make swap(QList&) available. + inline void swap(int i, int j) { QList::swap(i, j); } +#endif inline void enqueue(const T &t) { QList::append(t); } inline T dequeue() { return QList::takeFirst(); } inline T &head() { return QList::first(); } From 134c6db8587a8ce156d4fa31ffa62605821851b2 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 7 Mar 2015 07:20:50 +0400 Subject: [PATCH 09/25] [QFontEngineFT] Consolidate .*lpha.*MapForGlyph() behavior ...and decrease code duplication. Change-Id: I5eb3c0694dde9030405a3bd3d410ff9784ed7717 Reviewed-by: Lars Knoll --- src/gui/text/qfontengine_ft.cpp | 123 ++++++++++++++------------------ 1 file changed, 52 insertions(+), 71 deletions(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 8176ede994..03b9e6ef99 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1725,6 +1725,33 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe return overall; } +static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEngine::GlyphFormat glyphFormat) +{ + if (glyph == Q_NULLPTR) + return QImage(); + + QImage::Format format; + int bytesPerLine; + switch (glyphFormat) { + case QFontEngine::Format_Mono: + format = QImage::Format_Mono; + bytesPerLine = ((glyph->width + 31) & ~31) >> 3; + break; + case QFontEngine::Format_A8: + format = QImage::Format_Alpha8; + bytesPerLine = (glyph->width + 3) & ~3; + break; + case QFontEngine::Format_A32: + format = QImage::Format_ARGB32; + bytesPerLine = glyph->width * 4; + break; + default: + Q_UNREACHABLE(); + }; + + return QImage(static_cast(glyph->data), glyph->width, glyph->height, bytesPerLine, format); +} + QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixelPosition, QFontEngine::GlyphFormat neededFormat, const QTransform &t, QPoint *offset) @@ -1739,22 +1766,6 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe else if (neededFormat == Format_None) neededFormat = Format_A8; - QImage::Format format; - switch (neededFormat) { - case Format_Mono: - format = QImage::Format_Mono; - break; - case Format_A8: - format = QImage::Format_Alpha8; - break; - case Format_A32: - format = QImage::Format_ARGB32; - break; - default: - Q_ASSERT(false); - format = QImage::Format_Invalid; - }; - QFontEngineFT::Glyph *glyph; if (cacheEnabled) { QGlyphSet *gset = loadGlyphSet(t); @@ -1787,38 +1798,20 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe glyph = loadGlyph(0, glyphIndex, subPixelPosition, neededFormat); } - if (glyph == 0 || glyph->data == 0 || glyph->width == 0 || glyph->height == 0) { - if (!cacheEnabled && glyph != &emptyGlyph) - delete glyph; - unlockFace(); - return 0; - } - - int pitch; - switch (neededFormat) { - case Format_Mono: - pitch = ((glyph->width + 31) & ~31) >> 3; - break; - case Format_A8: - pitch = (glyph->width + 3) & ~3; - break; - case Format_A32: - pitch = glyph->width * 4; - break; - default: - Q_ASSERT(false); - pitch = 0; - }; - - if (offset != 0) + if (offset != 0 && glyph != 0) *offset = QPoint(glyph->x, -glyph->y); - currentlyLockedAlphaMap = QImage(glyph->data, glyph->width, glyph->height, pitch, format); + currentlyLockedAlphaMap = alphaMapFromGlyphData(glyph, neededFormat); + if (!cacheEnabled && glyph != &emptyGlyph) { currentlyLockedAlphaMap = currentlyLockedAlphaMap.copy(); delete glyph; } - Q_ASSERT(!currentlyLockedAlphaMap.isNull()); + + if (currentlyLockedAlphaMap.isNull()) { + unlockFace(); + return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset); + } QImageData *data = currentlyLockedAlphaMap.data_ptr(); data->is_locked = true; @@ -1864,32 +1857,20 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition) QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t) { - Glyph *glyph = loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono, t); - if (!glyph || !glyph->data) { - if (!cacheEnabled && glyph != &emptyGlyph) - delete glyph; - return QFontEngine::alphaMapForGlyph(g); - } + const GlyphFormat neededFormat = antialias ? Format_A8 : Format_Mono; - const int pitch = antialias ? (glyph->width + 3) & ~3 : ((glyph->width + 31)/32) * 4; + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); - QImage img(glyph->width, glyph->height, antialias ? QImage::Format_Alpha8 : QImage::Format_Mono); - if (!antialias) { - QVector colors(2); - colors[0] = qRgba(0, 0, 0, 0); - colors[1] = qRgba(0, 0, 0, 255); - img.setColorTable(colors); - } - Q_ASSERT(img.bytesPerLine() == pitch); - if (glyph->width) { - for (int y = 0; y < glyph->height; ++y) - memcpy(img.scanLine(y), &glyph->data[y * pitch], pitch); - } + QImage img = alphaMapFromGlyphData(glyph, neededFormat); + img = img.copy(); if (!cacheEnabled && glyph != &emptyGlyph) delete glyph; - return img; + if (!img.isNull()) + return img; + + return QFontEngine::alphaMapForGlyph(g); } QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t) @@ -1897,20 +1878,20 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co if (t.type() > QTransform::TxRotate) return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); - Glyph *glyph = loadGlyphFor(g, subPixelPosition, Format_A32, t); - if (!glyph || !glyph->data) { - if (!cacheEnabled && glyph != &emptyGlyph) - delete glyph; - return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); - } + const GlyphFormat neededFormat = Format_A32; - QImage img(glyph->width, glyph->height, QImage::Format_RGB32); - memcpy(img.bits(), glyph->data, 4 * glyph->width * glyph->height); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); + + QImage img = alphaMapFromGlyphData(glyph, neededFormat); + img = img.copy(); if (!cacheEnabled && glyph != &emptyGlyph) delete glyph; - return img; + if (!img.isNull()) + return img; + + return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); } void QFontEngineFT::removeGlyphFromCache(glyph_t glyph) From 3fb6014ce71febe1cb18ceaff16840bb4aea7deb Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 7 Mar 2015 08:01:42 +0400 Subject: [PATCH 10/25] [QFontEngineFT] Guarantee correct metrics for alphamap and its bounding box ...for both cached and non-cached modes, by disabling hinting for transformed glyphs in loadGlyphFor(). Change-Id: I13766a653ebd72cbed0f5c38ca3536d042aed762 Reviewed-by: Lars Knoll --- src/gui/painting/qtextureglyphcache.cpp | 11 ------ src/gui/text/qfontengine_ft.cpp | 46 +++++-------------------- 2 files changed, 8 insertions(+), 49 deletions(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 881fae9afc..4c879cf05d 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -123,17 +123,6 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const if (listItemCoordinates.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition))) continue; - // This is a rather crude hack, but it works. - // The FreeType font engine is not capable of getting precise metrics for the alphamap - // without first rasterizing the glyph. If we force the glyph to be rasterized before - // we ask for the alphaMapBoundingBox(), the glyph will be loaded, rasterized and its - // proper metrics will be cached and used later. - if (fontEngine->hasInternalCaching()) { - QImage *locked = fontEngine->lockedAlphaMapForGlyph(glyph, subPixelPosition, m_format); - if (locked && !locked->isNull()) - fontEngine->unlockAlphaMapForGlyph(); - } - glyph_metrics_t metrics = fontEngine->alphaMapBoundingBox(glyph, subPixelPosition, m_transform, m_format); #ifdef CACHE_DEBUG diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 03b9e6ef99..0437561572 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -43,6 +43,7 @@ #include "qfile.h" #include "qfileinfo.h" +#include #include "qthreadstorage.h" #include @@ -1757,7 +1758,6 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe const QTransform &t, QPoint *offset) { Q_ASSERT(currentlyLockedAlphaMap.isNull()); - lockFace(); if (isBitmapFont()) neededFormat = Format_Mono; @@ -1766,37 +1766,7 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe else if (neededFormat == Format_None) neededFormat = Format_A8; - QFontEngineFT::Glyph *glyph; - if (cacheEnabled) { - QGlyphSet *gset = loadGlyphSet(t); - QFontEngine::HintStyle hintStyle = default_hint_style; - if (t.type() >= QTransform::TxScale) { - // disable hinting if the glyphs are transformed - default_hint_style = HintNone; - } - - if (gset) { - FT_Matrix m = matrix; - FT_Matrix_Multiply(&gset->transformationMatrix, &m); - FT_Set_Transform(freetype->face, &m, 0); - freetype->matrix = m; - } - - if (!gset || gset->outline_drawing || !(glyph = loadGlyph(gset, glyphIndex, subPixelPosition, - neededFormat))) { - default_hint_style = hintStyle; - return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, - offset); - } - default_hint_style = hintStyle; - } else { - FT_Matrix m = matrix; - FT_Matrix extra = QTransformToFTMatrix(t); - FT_Matrix_Multiply(&extra, &m); - FT_Set_Transform(freetype->face, &m, 0); - freetype->matrix = m; - glyph = loadGlyph(0, glyphIndex, subPixelPosition, neededFormat); - } + Glyph *glyph = loadGlyphFor(glyphIndex, subPixelPosition, neededFormat, t); if (offset != 0 && glyph != 0) *offset = QPoint(glyph->x, -glyph->y); @@ -1808,10 +1778,8 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe delete glyph; } - if (currentlyLockedAlphaMap.isNull()) { - unlockFace(); + if (currentlyLockedAlphaMap.isNull()) return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset); - } QImageData *data = currentlyLockedAlphaMap.data_ptr(); data->is_locked = true; @@ -1821,9 +1789,7 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe void QFontEngineFT::unlockAlphaMapForGlyph() { - Q_ASSERT(!currentlyLockedAlphaMap.isNull()); - unlockFace(); - currentlyLockedAlphaMap = QImage(); + QFontEngine::unlockAlphaMapForGlyph(); } QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, @@ -1838,6 +1804,10 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0; if (!glyph || glyph->format != format || (!fetchBoundingBox && !glyph->data)) { + QScopedValueRollback saved_default_hint_style(default_hint_style); + if (t.type() >= QTransform::TxScale) + default_hint_style = HintNone; // disable hinting if the glyphs are transformed + lockFace(); FT_Matrix m = this->matrix; FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t); From 95d034a14f78aaefd6990de180f715c8b4d510b1 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 26 Feb 2015 18:04:43 +0400 Subject: [PATCH 11/25] Introduce QQuaternion::fromDirection() ...which constructs a quaternion using specified forward and upward directions, so that the resulting Z axis "faces" a given forward direction. Change-Id: Ib77b8ab5c359a4880b0d946face87026acdc6f0b Reviewed-by: Paul Lemire Reviewed-by: Michael Krasnyk Reviewed-by: Lars Knoll --- src/gui/math3d/qquaternion.cpp | 30 ++++++ src/gui/math3d/qquaternion.h | 2 + .../math3d/qquaternion/tst_qquaternion.cpp | 94 +++++++++++++++++++ 3 files changed, 126 insertions(+) diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 6914a0b45e..4b35ee4e79 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -717,11 +717,41 @@ QQuaternion QQuaternion::fromAxes(const QVector3D &xAxis, const QVector3D &yAxis return QQuaternion::fromRotationMatrix(rot3x3); } +/*! + \since 5.5 + + Constructs the quaternion using specified forward direction \a direction + and upward direction \a up. + If the upward direction was not specified or the forward and upward + vectors are collinear, a new orthonormal upward direction will be generated. + + \sa fromAxes(), rotationTo() +*/ +QQuaternion QQuaternion::fromDirection(const QVector3D &direction, const QVector3D &up) +{ + if (qFuzzyIsNull(direction.x()) && qFuzzyIsNull(direction.y()) && qFuzzyIsNull(direction.z())) + return QQuaternion(); + + const QVector3D zAxis(direction.normalized()); + QVector3D xAxis(QVector3D::crossProduct(up, zAxis)); + if (qFuzzyIsNull(xAxis.lengthSquared())) { + // collinear or invalid up vector; derive shortest arc to new direction + return QQuaternion::rotationTo(QVector3D(0.0f, 0.0f, 1.0f), zAxis); + } + + xAxis.normalize(); + const QVector3D yAxis(QVector3D::crossProduct(zAxis, xAxis)); + + return QQuaternion::fromAxes(xAxis, yAxis, zAxis); +} + /*! \since 5.5 Returns the shortest arc quaternion to rotate from the direction described by the vector \a from to the direction described by the vector \a to. + + \sa fromDirection() */ QQuaternion QQuaternion::rotationTo(const QVector3D &from, const QVector3D &to) { diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index c3918645d4..240e31a5c2 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -138,6 +138,8 @@ public: void getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const; static QQuaternion fromAxes(const QVector3D &xAxis, const QVector3D &yAxis, const QVector3D &zAxis); + static QQuaternion fromDirection(const QVector3D &direction, const QVector3D &up); + static QQuaternion rotationTo(const QVector3D &from, const QVector3D &to); #endif diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp index 2c38e4c111..ec7af97f07 100644 --- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp @@ -141,6 +141,9 @@ private slots: void rotationTo_data(); void rotationTo(); + void fromDirection_data(); + void fromDirection(); + void fromEulerAngles_data(); void fromEulerAngles(); @@ -989,6 +992,97 @@ void tst_QQuaternion::rotationTo() QVERIFY(myFuzzyCompare(vec2, from)); } +static QByteArray testnameForAxis(const QVector3D &axis) +{ + QByteArray testname; + if (axis == QVector3D()) { + testname = "null"; + } else { + if (axis.x()) { + testname += axis.x() < 0 ? "-" : "+"; + testname += "X"; + } + if (axis.y()) { + testname += axis.y() < 0 ? "-" : "+"; + testname += "Y"; + } + if (axis.z()) { + testname += axis.z() < 0 ? "-" : "+"; + testname += "Z"; + } + } + return testname; +} + +// Test quaternion convertion to and from orthonormal axes. +void tst_QQuaternion::fromDirection_data() +{ + QTest::addColumn("direction"); + QTest::addColumn("up"); + + QList orientations; + orientations << QQuaternion(); + for (int angle = 45; angle <= 360; angle += 45) { + orientations << QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), angle) + << QQuaternion::fromAxisAndAngle(QVector3D(0, 1, 0), angle) + << QQuaternion::fromAxisAndAngle(QVector3D(0, 0, 1), angle) + << QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), angle) + * QQuaternion::fromAxisAndAngle(QVector3D(0, 1, 0), angle) + * QQuaternion::fromAxisAndAngle(QVector3D(0, 0, 1), angle); + } + + // othonormal up and dir + foreach (const QQuaternion &q, orientations) { + QVector3D xAxis, yAxis, zAxis; + q.getAxes(&xAxis, &yAxis, &zAxis); + + QTest::newRow("dir: " + testnameForAxis(zAxis) + ", up: " + testnameForAxis(yAxis)) + << zAxis * 10.0f << yAxis * 10.0f; + } + + // collinear up and dir + QTest::newRow("dir: +X, up: +X") << QVector3D(10.0f, 0.0f, 0.0f) << QVector3D(10.0f, 0.0f, 0.0f); + QTest::newRow("dir: +X, up: -X") << QVector3D(10.0f, 0.0f, 0.0f) << QVector3D(-10.0f, 0.0f, 0.0f); + QTest::newRow("dir: +Y, up: +Y") << QVector3D(0.0f, 10.0f, 0.0f) << QVector3D(0.0f, 10.0f, 0.0f); + QTest::newRow("dir: +Y, up: -Y") << QVector3D(0.0f, 10.0f, 0.0f) << QVector3D(0.0f, -10.0f, 0.0f); + QTest::newRow("dir: +Z, up: +Z") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(0.0f, 0.0f, 10.0f); + QTest::newRow("dir: +Z, up: -Z") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(0.0f, 0.0f, -10.0f); + QTest::newRow("dir: +X+Y+Z, up: +X+Y+Z") << QVector3D(10.0f, 10.0f, 10.0f) << QVector3D(10.0f, 10.0f, 10.0f); + QTest::newRow("dir: +X+Y+Z, up: -X-Y-Z") << QVector3D(10.0f, 10.0f, 10.0f) << QVector3D(-10.0f, -10.0f, -10.0f); + + // invalid up + foreach (const QQuaternion &q, orientations) { + QVector3D xAxis, yAxis, zAxis; + q.getAxes(&xAxis, &yAxis, &zAxis); + + QTest::newRow("dir: " + testnameForAxis(zAxis) + ", up: null") + << zAxis * 10.0f << QVector3D(); + } +} +void tst_QQuaternion::fromDirection() +{ + QFETCH(QVector3D, direction); + QFETCH(QVector3D, up); + + QVector3D expextedZ(direction != QVector3D() ? direction.normalized() : QVector3D(0, 0, 1)); + QVector3D expextedY(up.normalized()); + + QQuaternion result = QQuaternion::fromDirection(direction, up); + QVERIFY(myFuzzyCompare(result, result.normalized())); + + QVector3D xAxis, yAxis, zAxis; + result.getAxes(&xAxis, &yAxis, &zAxis); + + QVERIFY(myFuzzyCompare(zAxis, expextedZ)); + + if (!qFuzzyIsNull(QVector3D::crossProduct(expextedZ, expextedY).lengthSquared())) { + QVector3D expextedX(QVector3D::crossProduct(expextedY, expextedZ)); + + QVERIFY(myFuzzyCompare(yAxis, expextedY)); + QVERIFY(myFuzzyCompare(xAxis, expextedX)); + } +} + // Test quaternion creation from an axis and an angle. void tst_QQuaternion::fromEulerAngles_data() { From 037ad03182ce3c174a5a9afc6780212bb2fe8a12 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 1 Apr 2015 06:54:45 +0400 Subject: [PATCH 12/25] [QFontEngineFT] Avoid double-negation of info.x Make it consistent with fetchMetricsOnly path. Change-Id: I6a2d2568d5579255582217515a4e598722547c60 Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/gui/text/qfontengine_ft.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 0437561572..7949bbc2a4 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -949,7 +949,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, info.height = slot->bitmap.rows / vfactor; info.width = hsubpixel ? slot->bitmap.width / 3 : slot->bitmap.width; - info.x = -slot->bitmap_left; + info.x = slot->bitmap_left; info.y = slot->bitmap_top; glyph_buffer_size = info.width * info.height * 4; @@ -1014,11 +1014,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, hpixels = hpixels*3 + 8; info.width = hpixels; info.height = TRUNC(top - bottom); - info.x = -TRUNC(left); + info.x = TRUNC(left); info.y = TRUNC(top); if (hsubpixel) { info.width /= 3; - info.x += 1; + info.x -= 1; } bool large_glyph = (((short)(slot->linearHoriAdvance>>10) != slot->linearHoriAdvance>>10) @@ -1146,7 +1146,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, g->linearAdvance = slot->linearHoriAdvance >> 10; g->width = info.width; g->height = info.height; - g->x = -info.x; + g->x = info.x; g->y = info.y; g->advance = info.xOff; g->format = format; From 550fb85b65549d1fc62aba214971578112431c92 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 7 Mar 2015 06:01:13 +0400 Subject: [PATCH 13/25] [QFontEngineFT] Move code around to improve readability (no-op) Move some variables initialization closer to the usage context. Change-Id: I0f1de0ddc9f0fbe3ec4a56455ccc14f9e8d94e5a Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/gui/text/qfontengine_ft.cpp | 35 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 7949bbc2a4..be98e8005f 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -808,13 +808,9 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, { // Q_ASSERT(freetype->lock == 1); - if (format == Format_None) { - if (defaultFormat != Format_None) { - format = defaultFormat; - } else { - format = Format_Mono; - } - } + if (format == Format_None) + format = defaultFormat != Format_None ? defaultFormat : Format_Mono; + Q_ASSERT(format != Format_None); Glyph *g = set ? set->getGlyph(glyph, subPixelPosition) : 0; if (g && g->format == format && (fetchMetricsOnly || g->data)) @@ -823,32 +819,28 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, if (!g && set && set->isGlyphMissing(glyph)) return &emptyGlyph; - QFontEngineFT::GlyphInfo info; - Q_ASSERT(format != Format_None); + FT_Face face = freetype->face; + + FT_Matrix matrix = freetype->matrix; + + FT_Vector v; + v.x = format == Format_Mono ? 0 : FT_Pos(subPixelPosition.value()); + v.y = 0; + FT_Set_Transform(face, &matrix, &v); + bool hsubpixel = false; int vfactor = 1; int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor); - if (format != Format_Mono && !embeddedbitmap) - load_flags |= FT_LOAD_NO_BITMAP; - - FT_Matrix matrix = freetype->matrix; bool transform = matrix.xx != 0x10000 || matrix.yy != 0x10000 || matrix.xy != 0 || matrix.yx != 0; - if (transform) + if (transform || (format != Format_Mono && !embeddedbitmap)) load_flags |= FT_LOAD_NO_BITMAP; - FT_Face face = freetype->face; - - FT_Vector v; - v.x = format == Format_Mono ? 0 : FT_Pos(subPixelPosition.toReal() * 64); - v.y = 0; - FT_Set_Transform(face, &freetype->matrix, &v); - FT_Error err = FT_Load_Glyph(face, glyph, load_flags); if (err && (load_flags & FT_LOAD_NO_BITMAP)) { load_flags &= ~FT_LOAD_NO_BITMAP; @@ -892,6 +884,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, FT_Matrix_Multiply(&m, &matrix); } + GlyphInfo info; info.xOff = TRUNC(ROUND(slot->advance.x)); info.yOff = 0; From 237cb0d082b5518cecf42f1a2186134799de745e Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 1 Apr 2015 10:56:39 +0400 Subject: [PATCH 14/25] [QFontEngineFT::loadGlyph] Consolidate paths for fetchMetricsOnly cases Use GlyphInfo as a temporary buffer for storing the glyph metrics and go through the same code for fetchMetricsOnly and !fetchMetricsOnly. Change-Id: If8bb85056e5f09588cc3956b43dc51a54d5aecfe Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/gui/text/qfontengine_ft.cpp | 51 +++++++++++++++++---------------- src/gui/text/qfontengine_ft_p.h | 1 + 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index be98e8005f..f8ce7112bc 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -801,6 +801,17 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags, return load_flags; } +static inline bool areMetricsTooLarge(const QFontEngineFT::GlyphInfo &info) +{ + // false if exceeds QFontEngineFT::Glyph metrics + return (short)(info.linearAdvance) == info.linearAdvance + && (signed char)(info.xOff) == info.xOff + && (uchar)(info.width) == info.width + && (uchar)(info.height) == info.height + && (signed char)(info.x) == info.x + && (signed char)(info.y) == info.y; +} + QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat format, @@ -885,6 +896,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, } GlyphInfo info; + info.linearAdvance = slot->linearHoriAdvance >> 10; info.xOff = TRUNC(ROUND(slot->advance.x)); info.yOff = 0; @@ -893,27 +905,23 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, int right = CEIL(slot->metrics.horiBearingX + slot->metrics.width); int top = CEIL(slot->metrics.horiBearingY); int bottom = FLOOR(slot->metrics.horiBearingY - slot->metrics.height); - int width = right-left; - int height = top-bottom; + info.x = TRUNC(left); + info.y = TRUNC(top); + info.width = TRUNC(right - left); + info.height = TRUNC(top - bottom); // If any of the metrics are too large to fit, don't cache them - if (qAbs(info.xOff) >= 128 - || qAbs(TRUNC(top)) >= 128 - || TRUNC(width) >= 256 - || TRUNC(height) >= 256 - || qAbs(TRUNC(left)) >= 128 - || qAbs(TRUNC(ROUND(slot->advance.x))) >= 128) { + if (areMetricsTooLarge(info)) return 0; - } g = new Glyph; g->data = 0; - g->linearAdvance = slot->linearHoriAdvance >> 10; - g->width = TRUNC(width); - g->height = TRUNC(height); - g->x = TRUNC(left); - g->y = TRUNC(top); - g->advance = TRUNC(ROUND(slot->advance.x)); + g->linearAdvance = info.linearAdvance; + g->width = info.width; + g->height = info.height; + g->x = info.x; + g->y = info.y; + g->advance = info.xOff; g->format = format; if (set) @@ -1014,16 +1022,9 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, info.x -= 1; } - bool large_glyph = (((short)(slot->linearHoriAdvance>>10) != slot->linearHoriAdvance>>10) - || ((uchar)(info.width) != info.width) - || ((uchar)(info.height) != info.height) - || ((signed char)(info.x) != info.x) - || ((signed char)(info.y) != info.y) - || ((signed char)(info.xOff) != info.xOff)); - - if (large_glyph) { + // If any of the metrics are too large to fit, don't cache them + if (areMetricsTooLarge(info)) return 0; - } int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 : (format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4)); @@ -1136,7 +1137,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, g->data = 0; } - g->linearAdvance = slot->linearHoriAdvance >> 10; + g->linearAdvance = info.linearAdvance; g->width = info.width; g->height = info.height; g->x = info.x; diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index e9d058d50c..7b28a4064f 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -143,6 +143,7 @@ public: }; struct GlyphInfo { + int linearAdvance; unsigned short width; unsigned short height; short x; From 3a845e4b4f308888ea1e3849d6bb03bccce99e43 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Tue, 7 Apr 2015 02:50:26 +0400 Subject: [PATCH 15/25] Use QT_WARNING_.. instead of #pragma GCC diagnostic .. Change-Id: I0bb55a7f1074f3b8d6fb681b1d4dab5105ae7569 Reviewed-by: Thiago Macieira --- src/corelib/tools/qarraydata.cpp | 10 +++------- src/plugins/platforms/windows/qwindowsfontdatabase.cpp | 10 +++------- .../printsupport/windows/qwindowsprintdevice.cpp | 6 ++---- src/testlib/qxctestlogger.mm | 7 ++++--- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index 513d9b4ae3..ef15fae83a 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -38,10 +38,8 @@ QT_BEGIN_NAMESPACE -#if defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) && !defined(Q_CC_INTEL) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") const QArrayData QArrayData::shared_null[2] = { { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, sizeof(QArrayData) }, // shared null @@ -52,9 +50,7 @@ static const QArrayData qt_array[3] = { { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, sizeof(QArrayData) }, // unsharable empty /* zero initialized terminator */}; -#if defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) && !defined(Q_CC_INTEL) - #pragma GCC diagnostic pop -#endif +QT_WARNING_POP static const QArrayData &qt_array_empty = qt_array[0]; static const QArrayData &qt_array_unsharable_empty = qt_array[1]; diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index d5708e4f9c..d1c0249116 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1104,18 +1104,14 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal GUID guid; CoCreateGuid(&guid); -#ifdef Q_CC_GNU -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif +QT_WARNING_PUSH +QT_WARNING_DISABLE_GCC("-Wstrict-aliasing") QString uniqueFamilyName = QLatin1Char('f') + QString::number(guid.Data1, 36) + QLatin1Char('-') + QString::number(guid.Data2, 36) + QLatin1Char('-') + QString::number(guid.Data3, 36) + QLatin1Char('-') + QString::number(*reinterpret_cast(guid.Data4), 36); -#ifdef Q_CC_GNU -# pragma GCC diagnostic pop -#endif +QT_WARNING_POP QString actualFontName = font.changeFamilyName(uniqueFamilyName); if (actualFontName.isEmpty()) { diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index b594fe9b34..af8e07edd2 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -39,14 +39,12 @@ # define DC_COLLATE 22 #endif -#if defined (Q_CC_MINGW) -# pragma GCC diagnostic ignored "-Wsign-compare" -#endif - QT_BEGIN_NAMESPACE #ifndef QT_NO_PRINTER +QT_WARNING_DISABLE_GCC("-Wsign-compare") + extern qreal qt_pointMultiplier(QPageLayout::Unit unit); static inline uint qwcsnlen(const wchar_t *str, uint maxlen) diff --git a/src/testlib/qxctestlogger.mm b/src/testlib/qxctestlogger.mm index 576f46acea..833e566af5 100644 --- a/src/testlib/qxctestlogger.mm +++ b/src/testlib/qxctestlogger.mm @@ -58,8 +58,9 @@ - (NSString *)nameForLegacyLogging; @end -#pragma GCC diagnostic push // Ignore XCTestProbe deprecation -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +QT_WARNING_PUSH +// Ignore XCTestProbe deprecation +QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations") // --------------------------------------------------------- @@ -498,4 +499,4 @@ bool QXcodeTestLogger::isActive() return s_currentTestLogger; } -#pragma GCC diagnostic pop +QT_WARNING_POP From 491b746473cf205cb08f64a2b1633a09d3c33ac4 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Tue, 7 Apr 2015 04:11:35 +0400 Subject: [PATCH 16/25] Fix build with -directwrite There were several issues caught by GCC: * deleting object of polymorphic class type which has non-virtual destructor might cause undefined behaviour * comparison between signed and unsigned integer expressions * 'GetUserDefaultLocaleName' was not declared in this scope (depends on WINVER >= 0x0600) Change-Id: I39f2cc0d5e158f4d85377edd55e9f74a512c7303 Reviewed-by: Lars Knoll Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/windows/qwindowsfontdatabase.cpp | 8 +++----- .../windows/qwindowsfontenginedirectwrite.cpp | 10 +++++++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index d1c0249116..b979dc6c4e 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -303,8 +303,7 @@ namespace { , m_referenceCount(0) { } - - ~DirectWriteFontFileStream() + virtual ~DirectWriteFontFileStream() { } @@ -355,7 +354,7 @@ namespace { OUT void **fragmentContext) { *fragmentContext = NULL; - if (fragmentSize + fileOffset <= m_fontData.size()) { + if (fileOffset + fragmentSize <= quint64(m_fontData.size())) { *fragmentStart = m_fontData.data() + fileOffset; return S_OK; } else { @@ -384,8 +383,7 @@ namespace { { public: DirectWriteFontFileLoader() : m_referenceCount(0) {} - - ~DirectWriteFontFileLoader() + virtual ~DirectWriteFontFileLoader() { } diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 85cd92b234..75449e22ed 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -33,6 +33,10 @@ #ifndef QT_NO_DIRECTWRITE +#if WINVER < 0x0600 +# undef WINVER +# define WINVER 0x0600 +#endif #if _WIN32_WINNT < 0x0600 #undef _WIN32_WINNT #define _WIN32_WINNT 0x0600 @@ -61,10 +65,14 @@ namespace { class GeometrySink: public IDWriteGeometrySink { public: - GeometrySink(QPainterPath *path) : m_path(path), m_refCount(0) + GeometrySink(QPainterPath *path) + : m_refCount(0), m_path(path) { Q_ASSERT(m_path != 0); } + virtual ~GeometrySink() + { + } IFACEMETHOD_(void, AddBeziers)(const D2D1_BEZIER_SEGMENT *beziers, UINT bezierCount); IFACEMETHOD_(void, AddLines)(const D2D1_POINT_2F *points, UINT pointCount); From 2a6249c00ad66e7b670acb18d4b1eec7508ac3d9 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Mon, 30 Mar 2015 15:31:55 +0200 Subject: [PATCH 17/25] Doc: Qt Concurrent: Link to essential usage information Functions under the QtConcurrent namespace used to be documented as header files, using the \headerfile command. These documents have been since converted to standard pages using the \page command, and the reference documentation for these functions now live in the namespace page only. However, the former pages contain useful usage information and code snippets, but they've not been linked to from anywhere. This change links to these pages from the module landing page, as well as from the function reference doc. Change-Id: Ia750d72d12503cec96ee2c9e202dd561e548cb24 Task-number: QTBUG-28977 Reviewed-by: Venugopal Shivashankar Reviewed-by: Leena Miettinen Reviewed-by: Sze Howe Koh --- .../doc/src/qtconcurrent-index.qdoc | 45 +++++++++++-------- src/concurrent/qtconcurrentfilter.cpp | 20 +++++++-- src/concurrent/qtconcurrentmap.cpp | 24 +++++++--- src/concurrent/qtconcurrentrun.cpp | 4 ++ 4 files changed, 65 insertions(+), 28 deletions(-) diff --git a/src/concurrent/doc/src/qtconcurrent-index.qdoc b/src/concurrent/doc/src/qtconcurrent-index.qdoc index 2157280021..e57ebd2424 100644 --- a/src/concurrent/doc/src/qtconcurrent-index.qdoc +++ b/src/concurrent/doc/src/qtconcurrent-index.qdoc @@ -49,26 +49,35 @@ applications: \list + \li \l {Concurrent Map and Map-Reduce} + \list + \li \l {QtConcurrent::map}{QtConcurrent::map()} applies a function + to every item in a container, modifying the items in-place. + \li \l {QtConcurrent::mapped}{QtConcurrent::mapped()} is like + map(), except that it returns a new container with the + modifications. + \li \l {QtConcurrent::mappedReduced}{QtConcurrent::mappedReduced()} + is like mapped(), except that the modified results are reduced + or folded into a single result. + \endlist - \li \l {QtConcurrent::map}{QtConcurrent::map()} applies a function to every item in a container, - modifying the items in-place. + \li \l {Concurrent Filter and Filter-Reduce} + \list + \li \l {QtConcurrent::filter}{QtConcurrent::filter()} removes all items + from a container based on the result of a filter function. + \li \l {QtConcurrent::filtered}{QtConcurrent::filtered()} is like + filter(), except that it returns a new container with the filtered + results. + \li \l {QtConcurrent::filteredReduced}{QtConcurrent::filteredReduced()} + is like filtered(), except that the filtered results are reduced or + folded into a single result. + \endlist - \li \l {QtConcurrent::mapped}{QtConcurrent::mapped()} is like map(), except that it returns a new - container with the modifications. - - \li \l {QtConcurrent::mappedReduced}{QtConcurrent::mappedReduced()} is like mapped(), except that the - modified results are reduced or folded into a single result. - - \li \l {QtConcurrent::filter}{QtConcurrent::filter()} removes all items from a container based on the - result of a filter function. - - \li \l {QtConcurrent::filtered}{QtConcurrent::filtered()} is like filter(), except that it returns a new - container with the filtered results. - - \li \l {QtConcurrent::filteredReduced}{QtConcurrent::filteredReduced()} is like filtered(), except that the - filtered results are reduced or folded into a single result. - - \li \l {QtConcurrent::run}{QtConcurrent::run()} runs a function in another thread. + \li \l {Concurrent Run} + \list + \li \l {QtConcurrent::run}{QtConcurrent::run()} runs a function in + another thread. + \endlist \li QFuture represents the result of an asynchronous computation. diff --git a/src/concurrent/qtconcurrentfilter.cpp b/src/concurrent/qtconcurrentfilter.cpp index 2c539b5766..4b3f2368b8 100644 --- a/src/concurrent/qtconcurrentfilter.cpp +++ b/src/concurrent/qtconcurrentfilter.cpp @@ -179,6 +179,8 @@ Calls \a filterFunction once for each item in \a sequence. If \a filterFunction returns \c true, the item is kept in \a sequence; otherwise, the item is removed from \a sequence. + + \sa {Concurrent Filter and Filter-Reduce} */ /*! @@ -188,6 +190,8 @@ new Sequence of kept items. If \a filterFunction returns \c true, a copy of the item is put in the new Sequence. Otherwise, the item will \e not appear in the new Sequence. + + \sa {Concurrent Filter and Filter-Reduce} */ /*! @@ -197,6 +201,8 @@ returns a new Sequence of kept items. If \a filterFunction returns \c true, a copy of the item is put in the new Sequence. Otherwise, the item will \e not appear in the new Sequence. + + \sa {Concurrent Filter and Filter-Reduce} */ /*! @@ -213,6 +219,8 @@ QtConcurrent::UnorderedReduce. If \a reduceOptions is QtConcurrent::OrderedReduce, \a reduceFunction is called in the order of the original sequence. + + \sa {Concurrent Filter and Filter-Reduce} */ /*! @@ -229,6 +237,8 @@ QtConcurrent::UnorderedReduce. If \a reduceOptions is QtConcurrent::OrderedReduce, the \a reduceFunction is called in the order of the original sequence. + + \sa {Concurrent Filter and Filter-Reduce} */ /*! @@ -239,6 +249,8 @@ otherwise, the item is removed from \a sequence. \note This function will block until all items in the sequence have been processed. + + \sa {Concurrent Filter and Filter-Reduce} */ /*! @@ -251,7 +263,7 @@ \note This function will block until all items in the sequence have been processed. - \sa filtered() + \sa filtered(), {Concurrent Filter and Filter-Reduce} */ /*! @@ -265,7 +277,7 @@ \note This function will block until the iterator reaches the end of the sequence being processed. - \sa filtered() + \sa filtered(), {Concurrent Filter and Filter-Reduce} */ /*! @@ -285,7 +297,7 @@ \note This function will block until all items in the sequence have been processed. - \sa filteredReduced() + \sa filteredReduced(), {Concurrent Filter and Filter-Reduce} */ /*! @@ -306,5 +318,5 @@ \note This function will block until the iterator reaches the end of the sequence being processed. - \sa filteredReduced() + \sa filteredReduced(), {Concurrent Filter and Filter-Reduce} */ diff --git a/src/concurrent/qtconcurrentmap.cpp b/src/concurrent/qtconcurrentmap.cpp index 43ade3a336..158bdb3887 100644 --- a/src/concurrent/qtconcurrentmap.cpp +++ b/src/concurrent/qtconcurrentmap.cpp @@ -229,6 +229,8 @@ Calls \a function once for each item in \a sequence. The \a function is passed a reference to the item, so that any modifications done to the item will appear in \a sequence. + + \sa {Concurrent Map and Map-Reduce} */ /*! @@ -237,6 +239,8 @@ Calls \a function once for each item from \a begin to \a end. The \a function is passed a reference to the item, so that any modifications done to the item will appear in the sequence which the iterators belong to. + + \sa {Concurrent Map and Map-Reduce} */ /*! @@ -245,6 +249,8 @@ Calls \a function once for each item in \a sequence and returns a future with each mapped item as a result. You can use QFuture::const_iterator or QFutureIterator to iterate through the results. + + \sa {Concurrent Map and Map-Reduce} */ /*! @@ -253,6 +259,8 @@ Calls \a function once for each item from \a begin to \a end and returns a future with each mapped item as a result. You can use QFuture::const_iterator or QFutureIterator to iterate through the results. + + \sa {Concurrent Map and Map-Reduce} */ /*! @@ -266,6 +274,8 @@ Note that while \a mapFunction is called concurrently, only one thread at a time will call \a reduceFunction. The order in which \a reduceFunction is called is determined by \a reduceOptions. + + \sa {Concurrent Map and Map-Reduce} */ /*! @@ -281,6 +291,8 @@ \a reduceFunction is called is undefined. \note QtConcurrent::OrderedReduce results in the ordered reduction. + + \sa {Concurrent Map and Map-Reduce} */ /*! @@ -292,7 +304,7 @@ \note This function will block until all items in the sequence have been processed. - \sa map() + \sa map(), {Concurrent Map and Map-Reduce} */ /*! @@ -305,7 +317,7 @@ \note This function will block until the iterator reaches the end of the sequence being processed. - \sa map() + \sa map(), {Concurrent Map and Map-Reduce} */ /*! @@ -316,7 +328,7 @@ \note This function will block until all items in the sequence have been processed. - \sa mapped() + \sa mapped(), {Concurrent Map and Map-Reduce} */ /*! @@ -333,7 +345,7 @@ \note This function will block until the iterator reaches the end of the sequence being processed. - \sa mapped() + \sa mapped(), {Concurrent Map and Map-Reduce} */ /*! @@ -348,7 +360,7 @@ \note This function will block until all items in the sequence have been processed. - \sa mapped() + \sa mapped(), {Concurrent Map and Map-Reduce} */ /*! @@ -364,5 +376,5 @@ \note This function will block until the iterator reaches the end of the sequence being processed. - \sa blockingMappedReduced() + \sa blockingMappedReduced(), {Concurrent Map and Map-Reduce} */ diff --git a/src/concurrent/qtconcurrentrun.cpp b/src/concurrent/qtconcurrentrun.cpp index 42d085cc2a..fa791bd323 100644 --- a/src/concurrent/qtconcurrentrun.cpp +++ b/src/concurrent/qtconcurrentrun.cpp @@ -143,6 +143,8 @@ canceling, pausing, or progress reporting. The QFuture returned can only be used to query for the running/finished status and the return value of the function. + + \sa {Concurrent Run} */ /*! @@ -160,4 +162,6 @@ canceling, pausing, or progress reporting. The QFuture returned can only be used to query for the running/finished status and the return value of the function. + + \sa {Concurrent Run} */ From 22dbf6111ddbbf7e692157f7f7eacaf776013ac0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 14 Jan 2015 16:57:21 -0800 Subject: [PATCH 18/25] Remove unnecessary QDateTime::detach() function Last commit changed QDateTime::d to be a QSharedDataPointer that implicitly detaches on non-const operator->() calls. That means we no longer need to explicitly call detach(). More than that, we should not do it, so we avoid checking the ref count and try to detach on every use. To do that, in functions where the d pointer was accessed more than once, I detach at the top and shadow the "d" variable with a local plain pointer. We don't compile our sources with -Wshadow, so this should not be a problem. Change-Id: Ic5d393bfd36e48a193fcffff13b969c281c36d0c Reviewed-by: Lars Knoll --- src/corelib/tools/qdatetime.cpp | 25 ++++--------------------- src/corelib/tools/qdatetime.h | 1 - 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 67f16e1f49..e445055e1d 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -3237,7 +3237,6 @@ bool QDateTime::isDaylightTime() const void QDateTime::setDate(const QDate &date) { - detach(); d->setDateTime(date, time()); } @@ -3256,7 +3255,6 @@ void QDateTime::setDate(const QDate &date) void QDateTime::setTime(const QTime &time) { - detach(); d->setDateTime(date(), time); } @@ -3278,7 +3276,7 @@ void QDateTime::setTime(const QTime &time) void QDateTime::setTimeSpec(Qt::TimeSpec spec) { - detach(); + QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) d->setTimeSpec(spec, 0); d->checkValidDateTime(); } @@ -3300,7 +3298,7 @@ void QDateTime::setTimeSpec(Qt::TimeSpec spec) void QDateTime::setOffsetFromUtc(int offsetSeconds) { - detach(); + QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) d->setTimeSpec(Qt::OffsetFromUTC, offsetSeconds); d->checkValidDateTime(); } @@ -3319,7 +3317,7 @@ void QDateTime::setOffsetFromUtc(int offsetSeconds) void QDateTime::setTimeZone(const QTimeZone &toZone) { - detach(); + QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) d->m_spec = Qt::TimeZone; d->m_offsetFromUtc = 0; d->m_timeZone = toZone; @@ -3395,7 +3393,7 @@ uint QDateTime::toTime_t() const */ void QDateTime::setMSecsSinceEpoch(qint64 msecs) { - detach(); + QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) d->m_status = 0; switch (d->m_spec) { @@ -3669,7 +3667,6 @@ QString QDateTime::toString(const QString& format) const QDateTime QDateTime::addDays(qint64 ndays) const { QDateTime dt(*this); - dt.detach(); QPair p = d->getDateTime(); QDate &date = p.first; QTime &time = p.second; @@ -3705,7 +3702,6 @@ QDateTime QDateTime::addDays(qint64 ndays) const QDateTime QDateTime::addMonths(int nmonths) const { QDateTime dt(*this); - dt.detach(); QPair p = d->getDateTime(); QDate &date = p.first; QTime &time = p.second; @@ -3741,7 +3737,6 @@ QDateTime QDateTime::addMonths(int nmonths) const QDateTime QDateTime::addYears(int nyears) const { QDateTime dt(*this); - dt.detach(); QPair p = d->getDateTime(); QDate &date = p.first; QTime &time = p.second; @@ -3790,7 +3785,6 @@ QDateTime QDateTime::addMSecs(qint64 msecs) const return QDateTime(); QDateTime dt(*this); - dt.detach(); if (d->m_spec == Qt::LocalTime || d->m_spec == Qt::TimeZone) // Convert to real UTC first in case crosses daylight transition dt.setMSecsSinceEpoch(d->toMSecsSinceEpoch() + msecs); @@ -4267,7 +4261,6 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs) QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetSeconds) { QDateTime dt; - dt.detach(); dt.d->setTimeSpec(spec, offsetSeconds); dt.setMSecsSinceEpoch(msecs); return dt; @@ -4687,14 +4680,6 @@ QDateTime QDateTime::fromString(const QString &string, const QString &format) \sa toTimeSpec() */ -/*! - \internal - */ -void QDateTime::detach() -{ - d.detach(); -} - /***************************************************************************** Date/time stream functions *****************************************************************************/ @@ -4846,8 +4831,6 @@ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) QDataStream &operator>>(QDataStream &in, QDateTime &dateTime) { - dateTime.detach(); - QDate dt; QTime tm; qint8 ts = 0; diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index 88288872df..78ec2b156a 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -321,7 +321,6 @@ public: private: friend class QDateTimePrivate; - void detach(); // ### Qt6: Using a private here has high impact on runtime // on users such as QFileInfo. In Qt 6, the data members From dc6e964f636d36448259af0061f077c86c081d98 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 7 Apr 2015 15:34:46 +0200 Subject: [PATCH 19/25] docs: QString contains characters, not items Change-Id: I479a731780dfce81e138d1aca950385437266763 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qstring.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index a0067178ac..fe77e77c2b 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1291,7 +1291,7 @@ const QString::Null QString::null = { }; \since 5.0 Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary - item after the last item in the list. + character after the last character in the list. \sa cbegin(), end() */ @@ -1299,7 +1299,7 @@ const QString::Null QString::null = { }; /*! \fn QString::const_iterator QString::constEnd() const Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary - item after the last item in the list. + character after the last character in the list. \sa constBegin(), end() */ From 8780381532d8350c47a66e6588a569eec396b133 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 7 Apr 2015 15:51:47 +0200 Subject: [PATCH 20/25] QByteArray: begin()/end() are not \internal Docs copied from corresponding QString functions. Change-Id: Ia2b0f0521780246d82003a1fda539c132823b294 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qbytearray.cpp | 34 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index eb96757457..da5d00311a 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -869,44 +869,62 @@ static inline char qToLower(char c) /*! \fn QByteArray::iterator QByteArray::begin() - \internal + Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first character in + the byte-array. + + \sa constBegin(), end() */ /*! \fn QByteArray::const_iterator QByteArray::begin() const - \internal + \overload begin() */ /*! \fn QByteArray::const_iterator QByteArray::cbegin() const \since 5.0 - \internal + Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first character + in the byte-array. + + \sa begin(), cend() */ /*! \fn QByteArray::const_iterator QByteArray::constBegin() const - \internal + Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first character + in the byte-array. + + \sa begin(), constEnd() */ /*! \fn QByteArray::iterator QByteArray::end() - \internal + Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary character + after the last character in the byte-array. + + \sa begin(), constEnd() */ /*! \fn QByteArray::const_iterator QByteArray::end() const - \internal + \overload end() */ /*! \fn QByteArray::const_iterator QByteArray::cend() const \since 5.0 - \internal + Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary + character after the last character in the list. + + \sa cbegin(), end() */ /*! \fn QByteArray::const_iterator QByteArray::constEnd() const - \internal + Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary + character after the last character in the list. + + \sa constBegin(), end() */ /*! \fn void QByteArray::push_back(const QByteArray &other) From f041757d7a9e76c8463609d8169339b4b0dae3f6 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 2 Apr 2015 15:59:51 +0200 Subject: [PATCH 21/25] Allow overriding ar binary in configure script by setting AR env var Unlike all the QMAKE_* command variables it requires the arguments "cqs" to be part of the variable. This means we need to append the arguments for compatibility with autoconf. Change-Id: I961e89d506612873ba1f9cbecff97c448e83a5a2 Reviewed-by: Oswald Buddenhagen --- configure | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 35a50ebb3b..4addf22896 100755 --- a/configure +++ b/configure @@ -561,21 +561,28 @@ fi # initalize variables #------------------------------------------------------------------------------- -SYSTEM_VARIABLES="RANLIB STRIP OBJDUMP LD CC CXX CFLAGS CXXFLAGS LDFLAGS" +SYSTEM_VARIABLES="AR RANLIB STRIP OBJDUMP LD CC CXX CFLAGS CXXFLAGS LDFLAGS" for varname in $SYSTEM_VARIABLES; do qmakevarname="${varname}" + qmakecmdargs="" # use LDFLAGS for autoconf compat, but qmake uses QMAKE_LFLAGS if [ "${varname}" = "LDFLAGS" ]; then qmakevarname="LFLAGS" elif [ "${varname}" = "LD" ]; then qmakevarname="LINK" + elif [ "${varname}" = "AR" ]; then + # QMAKE_AR needs to be set to "/path/to/ar cqs" but the + # environment variable will be set to the command only so we + # need to append " cqs" for autoconf compatibility + qmakecmdargs=" cqs" fi cmd=`echo \ 'if [ -n "\$'${varname}'" ]; then - QMakeVar set QMAKE_'${qmakevarname}' "\$'${varname}'" + QMakeVar set QMAKE_'${qmakevarname}' "\$'${varname}${qmakecmdargs}'" fi'` eval "$cmd" done + # Use CC/CXX to run config.tests mkdir -p "$outpath/config.tests" rm -f "$outpath/config.tests/.qmake.cache" From a715c6ceb8cd59b44f75a08cd6a7095f2ceac04d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 31 Mar 2015 12:32:33 +0200 Subject: [PATCH 22/25] Use the default fbo in Qt sense in blitFramebuffer QOpenGLFramebufferObject::blitFramebuffer() passes 0 when no FBO is specified. This goes against the rest of the framework where the default fbo is what QOpenGLContext::defaultFramebufferObject() returns. This becomes significant with QOpenGLWidget and on iOS. Task-number: QTBUG-45328 Change-Id: Iaeb82cd3786ad395116679c9626bdcb10e93b4e3 Reviewed-by: Gunnar Sletta --- src/gui/opengl/qopenglframebufferobject.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index c4deeea4c9..8d298496df 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -1484,8 +1484,10 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const int ty0 = targetRect.top(); const int ty1 = targetRect.top() + targetRect.height(); - extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : 0); - extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : 0); + const GLuint defaultFboId = ctx->defaultFramebufferObject(); + + extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : defaultFboId); + extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : defaultFboId); extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1, tx0, ty0, tx1, ty1, From a60571b3700e80f44705ebc4bab9628cf852891c Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 23 Mar 2015 16:03:57 +0100 Subject: [PATCH 23/25] QSaveFile: Fix permissions on creation QSaveFile is intended to be a replacement for QFile, and should use the same permissions for newly created files. QTemporaryFile however creates new files with 0600 mask by default. Fix this by making the mode_t argument QTemporaryFileEngine uses configurable, and using 0666 for QSaveFile (like we do in QFile). [ChangeLog][Important behavior changes] Files created by QSaveFile do now have the same rights as files created by QFile. This also fixes a regression in QSettings: In the Qt 5.4 series, new files created by QSettings were only readable by the current user. Task-number: QTBUG-44086 Change-Id: Ie1cc20e9f25c6e72e1bc9176490c419c27c5fc82 Reviewed-by: Leena Miettinen Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/io/qsavefile.cpp | 2 +- src/corelib/io/qtemporaryfile.cpp | 13 ++++++++----- src/corelib/io/qtemporaryfile_p.h | 10 ++++++++-- tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp | 8 ++++++++ 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index 33be537433..ffa6ad1c55 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -215,7 +215,7 @@ bool QSaveFile::open(OpenMode mode) d->finalFileName = existingFile.filePath(); } - d->fileEngine = new QTemporaryFileEngine(d->finalFileName); + d->fileEngine = new QTemporaryFileEngine(d->finalFileName, 0666); // Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine. if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) { QFileDevice::FileError err = d->fileEngine->error(); diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index fa851a6d74..556bc6e760 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -103,13 +103,14 @@ typedef int NativeFileHandle; \a path is used as a template when generating unique paths, \a pos identifies the position of the first character that will be replaced in the template and \a length the number of characters that may be substituted. + \a mode specifies the file mode bits (not used on Windows). Returns an open handle to the newly created file if successful, an invalid handle otherwise. In both cases, the string in \a path will be changed and contain the generated path name. */ static bool createFileFromTemplate(NativeFileHandle &file, - QFileSystemEntry::NativePath &path, size_t pos, size_t length, + QFileSystemEntry::NativePath &path, size_t pos, size_t length, quint32 mode, QSystemError &error) { Q_ASSERT(length != 0); @@ -143,6 +144,8 @@ static bool createFileFromTemplate(NativeFileHandle &file, for (;;) { // Atomically create file and obtain handle #if defined(Q_OS_WIN) + Q_UNUSED(mode); + # ifndef Q_OS_WINRT file = CreateFile((const wchar_t *)path.constData(), GENERIC_READ | GENERIC_WRITE, @@ -175,7 +178,7 @@ static bool createFileFromTemplate(NativeFileHandle &file, #else // POSIX file = QT_OPEN(path.constData(), QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, - 0600); + static_cast(mode)); if (file != -1) return true; @@ -333,7 +336,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) NativeFileHandle &file = d->fd; #endif - if (!createFileFromTemplate(file, filename, phPos, phLength, error)) { + if (!createFileFromTemplate(file, filename, phPos, phLength, fileMode, error)) { setError(QFile::OpenError, error.toString()); return false; } @@ -407,9 +410,9 @@ QAbstractFileEngine *QTemporaryFilePrivate::engine() const { if (!fileEngine) { if (fileName.isEmpty()) - fileEngine = new QTemporaryFileEngine(templateName); + fileEngine = new QTemporaryFileEngine(templateName, 0600); else - fileEngine = new QTemporaryFileEngine(fileName, false); + fileEngine = new QTemporaryFileEngine(fileName, 0600, false); } return fileEngine; } diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h index 2045edff02..475298f264 100644 --- a/src/corelib/io/qtemporaryfile_p.h +++ b/src/corelib/io/qtemporaryfile_p.h @@ -77,8 +77,13 @@ class QTemporaryFileEngine : public QFSFileEngine { Q_DECLARE_PRIVATE(QFSFileEngine) public: - QTemporaryFileEngine(const QString &file, bool fileIsTemplate = true) - : QFSFileEngine(), filePathIsTemplate(fileIsTemplate), + + QTemporaryFileEngine(const QString &file, + quint32 fileMode, + bool fileIsTemplate = true) : + QFSFileEngine(), + fileMode(fileMode), + filePathIsTemplate(fileIsTemplate), filePathWasTemplate(fileIsTemplate) { Q_D(QFSFileEngine); @@ -100,6 +105,7 @@ public: bool renameOverwrite(const QString &newName); bool close(); + quint32 fileMode; bool filePathIsTemplate; bool filePathWasTemplate; }; diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp index 2c86f0f19c..5796636b92 100644 --- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp +++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp @@ -119,6 +119,14 @@ void tst_QSaveFile::transactionalWrite() QFile reader(targetFile); QVERIFY(reader.open(QIODevice::ReadOnly)); QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("Hello")); + + // check that permissions are the same as for QFile + const QString otherFile = dir.path() + QString::fromLatin1("/otherfile"); + QFile::remove(otherFile); + QFile other(otherFile); + other.open(QIODevice::WriteOnly); + other.close(); + QCOMPARE(QFile::permissions(targetFile), QFile::permissions(otherFile)); } void tst_QSaveFile::saveTwice() From a21a24ee485a2dc368d5e837cfc8aeb5c74717a1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 8 Apr 2015 09:12:39 +0200 Subject: [PATCH 24/25] [QFontEngineFT::loadGlyph] Fix reversed condition. Introduced by 237cb0d082b5518cecf42f1a2186134799de745e (Consolidate paths for fetchMetricsOnly cases). Task-number: QTBUG-45444 Change-Id: Icd642c09490f1cfc5804313d60d467290ae599ba Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- src/gui/text/qfontengine_ft.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index f8ce7112bc..931c71dc63 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -804,12 +804,12 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags, static inline bool areMetricsTooLarge(const QFontEngineFT::GlyphInfo &info) { // false if exceeds QFontEngineFT::Glyph metrics - return (short)(info.linearAdvance) == info.linearAdvance - && (signed char)(info.xOff) == info.xOff - && (uchar)(info.width) == info.width - && (uchar)(info.height) == info.height - && (signed char)(info.x) == info.x - && (signed char)(info.y) == info.y; + return (short)(info.linearAdvance) != info.linearAdvance + || (signed char)(info.xOff) != info.xOff + || (uchar)(info.width) != info.width + || (uchar)(info.height) != info.height + || (signed char)(info.x) != info.x + || (signed char)(info.y) != info.y; } QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, From 00540a8345c35703aeaab072fd9e4727c9b61d5a Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Fri, 3 Apr 2015 21:42:10 -0700 Subject: [PATCH 25/25] Remove special handling for (DY)LD_LIBRARY_PATH in QProcess. This provides the ability to pass a *real* clear environment to a QProcess, rather than (DY)LD_LIBRARY_PATH always being copied over from the current environment behind-the-scenes. This is important to users because passing a truly clear environment is now possible. [ChangeLog][Important Behavior Changes] (DY)LD_LIBRARY_PATH will no longer "stick" in the process environment when starting a QProcess. This means that if a QProcess is started with a clear environment, it will not specially inherit (DY)LD_LIBRARY_PATH from the parent process. This should not affect most applications, but if the old behavior is desired, one can simply pass a clear QProcessEnvironment with the (DY)LD_LIBRARY_PATH values added, to the QProcess. Change-Id: I51d1bc14905c5cc126fb02d91dddc2faade41a3c Reviewed-by: Thiago Macieira --- src/corelib/io/qprocess_unix.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index ffdf6f9e2e..46b557d6e0 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -299,18 +299,6 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm if (environment.isEmpty()) return 0; - // if LD_LIBRARY_PATH exists in the current environment, but - // not in the environment list passed by the programmer, then - // copy it over. -#if defined(Q_OS_MAC) - static const char libraryPath[] = "DYLD_LIBRARY_PATH"; -#else - static const char libraryPath[] = "LD_LIBRARY_PATH"; -#endif - const QByteArray envLibraryPath = qgetenv(libraryPath); - bool needToAddLibraryPath = !envLibraryPath.isEmpty() && - !environment.contains(QProcessEnvironmentPrivate::Key(QByteArray(libraryPath))); - char **envp = new char *[environment.count() + 2]; envp[environment.count()] = 0; envp[environment.count() + 1] = 0; @@ -327,9 +315,6 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm envp[(*envc)++] = ::strdup(key.constData()); } - if (needToAddLibraryPath) - envp[(*envc)++] = ::strdup(QByteArray(QByteArray(libraryPath) + '=' + - envLibraryPath).constData()); return envp; }