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" 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;"; } } } 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} */ 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; } 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/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/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) 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 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(); } diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 56dab68f33..6315c15818 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() */ 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/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, 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 8176ede994..931c71dc63 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 @@ -800,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, @@ -807,13 +819,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)) @@ -822,32 +830,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; @@ -891,6 +895,8 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, FT_Matrix_Multiply(&m, &matrix); } + GlyphInfo info; + info.linearAdvance = slot->linearHoriAdvance >> 10; info.xOff = TRUNC(ROUND(slot->advance.x)); info.yOff = 0; @@ -899,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) @@ -948,7 +950,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; @@ -1013,23 +1015,16 @@ 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) - || ((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)); @@ -1142,10 +1137,10 @@ 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; + g->x = info.x; g->y = info.y; g->advance = info.xOff; g->format = format; @@ -1725,12 +1720,38 @@ 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) { Q_ASSERT(currentlyLockedAlphaMap.isNull()); - lockFace(); if (isBitmapFont()) neededFormat = Format_Mono; @@ -1739,86 +1760,20 @@ 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; - }; + Glyph *glyph = loadGlyphFor(glyphIndex, subPixelPosition, neededFormat, t); - 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); - } - - 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()) + return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset); QImageData *data = currentlyLockedAlphaMap.data_ptr(); data->is_locked = true; @@ -1828,9 +1783,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, @@ -1845,6 +1798,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); @@ -1864,32 +1821,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 +1842,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) 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; diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index e978af1f3d..baecf27162 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(); } diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index d5708e4f9c..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() { } @@ -1104,18 +1102,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/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); 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 diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index 38e8d72b1b..6bb6f67809 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); } 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 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() 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() {