diff options
21 files changed, 278 insertions, 169 deletions
diff --git a/src/corelib/arch/qatomic_msvc.h b/src/corelib/arch/qatomic_msvc.h index 85889662fc..fc4d5a466a 100644 --- a/src/corelib/arch/qatomic_msvc.h +++ b/src/corelib/arch/qatomic_msvc.h @@ -42,7 +42,7 @@ // use compiler intrinsics for all atomic functions # define QT_INTERLOCKED_PREFIX _ -# define QT_INTERLOCKED_PROTOTYPE __cdecl +# define QT_INTERLOCKED_PROTOTYPE # define QT_INTERLOCKED_DECLARE_PROTOTYPES # define QT_INTERLOCKED_INTRINSIC # define Q_ATOMIC_INT16_IS_SUPPORTED diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index fa8a529d0c..6958912e67 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -173,7 +173,11 @@ # else # define Q_CC_CLANG ((__clang_major__ * 100) + __clang_minor__) # endif -# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable() +# if __has_builtin(__builtin_assume) +# define Q_ASSUME_IMPL(expr) __builtin_assume(expr) +# else +# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable() +# endif # define Q_UNREACHABLE_IMPL() __builtin_unreachable() # if !defined(__has_extension) # /* Compatibility with older Clang versions */ diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp index b0ee715c75..f55f68f9b3 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -40,6 +40,7 @@ #endif #include "qdebug.h" +#include "qmetaobject.h" #include <private/qtextstream_p.h> #include <private/qtools_p.h> @@ -284,12 +285,12 @@ void QDebug::putString(const QChar *begin, size_t length) if (stream->testFlag(Stream::NoQuotes)) { // no quotes, write the string directly too (no pretty-printing) // this respects the QTextStream state, though - stream->ts.d_ptr->putString(begin, length); + stream->ts.d_ptr->putString(begin, int(length)); } else { // we'll reset the QTextStream formatting mechanisms, so save the state QDebugStateSaver saver(*this); stream->ts.d_ptr->params.reset(); - putEscapedString(stream->ts.d_ptr.data(), reinterpret_cast<const ushort *>(begin), length); + putEscapedString(stream->ts.d_ptr.data(), reinterpret_cast<const ushort *>(begin), int(length)); } } @@ -302,14 +303,14 @@ void QDebug::putByteArray(const char *begin, size_t length, Latin1Content conten if (stream->testFlag(Stream::NoQuotes)) { // no quotes, write the string directly too (no pretty-printing) // this respects the QTextStream state, though - QString string = content == ContainsLatin1 ? QString::fromLatin1(begin, length) : QString::fromUtf8(begin, length); + QString string = content == ContainsLatin1 ? QString::fromLatin1(begin, int(length)) : QString::fromUtf8(begin, int(length)); stream->ts.d_ptr->putString(string); } else { // we'll reset the QTextStream formatting mechanisms, so save the state QDebugStateSaver saver(*this); stream->ts.d_ptr->params.reset(); putEscapedString(stream->ts.d_ptr.data(), reinterpret_cast<const uchar *>(begin), - length, content == ContainsLatin1); + int(length), content == ContainsLatin1); } } @@ -643,4 +644,23 @@ QDebugStateSaver::~QDebugStateSaver() d->restoreState(); } +#ifndef QT_NO_QOBJECT +/*! + \internal + */ +QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, int value, const QMetaObject *meta, const char *name) +{ + QDebugStateSaver saver(dbg); + QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name)); + const char *key = me.valueToKey(value); + dbg.nospace() << meta->className() << "::" << name << '('; + if (key) + dbg << key; + else + dbg << value; + dbg << ')'; + return dbg; +} +#endif + QT_END_NAMESPACE diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 56a5e1fa74..435e7450c7 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -261,6 +261,19 @@ inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache) return debug.maybeSpace(); } +#ifndef QT_NO_QOBJECT +Q_CORE_EXPORT QDebug qt_QMetaEnum_debugOperator(QDebug&, int value, const QMetaObject *meta, const char *name); + +template<typename T> +typename QtPrivate::QEnableIf<QtPrivate::IsQEnumHelper<T>::Value, QDebug>::Type +operator<<(QDebug dbg, T value) +{ + const QMetaObject *obj = qt_getEnumMetaObject(value); + const char *name = qt_getEnumName(value); + return qt_QMetaEnum_debugOperator(dbg, typename QFlags<T>::Int(value), obj, name); +} +#endif + template <class T> inline QDebug operator<<(QDebug debug, const QFlags<T> &flags) { diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 98e3f6b5bd..265cc68db5 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4106,20 +4106,6 @@ QDebug operator<<(QDebug dbg, const QObject *o) dbg << ')'; return dbg; } - -QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, int value, const QMetaObject *meta, const char *name) -{ - QDebugStateSaver saver(dbg); - QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name)); - const char *key = me.valueToKey(value); - dbg.nospace() << meta->className() << "::" << name << '('; - if (key) - dbg << key; - else - dbg << value; - dbg << ')'; - return dbg; -} #endif /*! diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index ae1c92f127..42d18d6c41 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -547,16 +547,6 @@ template <class T> inline const char * qobject_interface_iid() #ifndef QT_NO_DEBUG_STREAM Q_CORE_EXPORT QDebug operator<<(QDebug, const QObject *); -Q_CORE_EXPORT QDebug qt_QMetaEnum_debugOperator(QDebug&, int value, const QMetaObject *meta, const char *name); - -template<typename T> -typename QtPrivate::QEnableIf<QtPrivate::IsQEnumHelper<T>::Value , QDebug>::Type -operator<<(QDebug &dbg, T value) -{ - const QMetaObject *obj = qt_getEnumMetaObject(value); - const char *name = qt_getEnumName(value); - return qt_QMetaEnum_debugOperator(dbg, typename QFlags<T>::Int(value), obj, name); -} #endif class QSignalBlocker diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index aa35d764fa..beda0f4919 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -240,7 +240,7 @@ void qt_from_latin1(ushort *dst, const char *str, size_t size) dst += offset; str += offset; # ifdef Q_COMPILER_LAMBDA - return UnrollTailLoop<15>::exec(size, [=](int i) { dst[i] = (uchar)str[i]; }); + return UnrollTailLoop<15>::exec(int(size), [=](int i) { dst[i] = (uchar)str[i]; }); # endif #endif #if defined(__mips_dsp) diff --git a/src/corelib/tools/qtools_p.h b/src/corelib/tools/qtools_p.h index b48ed94236..3a407aea5b 100644 --- a/src/corelib/tools/qtools_p.h +++ b/src/corelib/tools/qtools_p.h @@ -63,9 +63,9 @@ Q_DECL_CONSTEXPR inline char toHexLower(uint value) Q_DECL_NOTHROW Q_DECL_CONSTEXPR inline int fromHex(uint c) Q_DECL_NOTHROW { - return ((c >= '0') && (c <= '9')) ? c - '0' : - ((c >= 'A') && (c <= 'F')) ? c - 'A' + 10 : - ((c >= 'a') && (c <= 'f')) ? c - 'a' + 10 : + return ((c >= '0') && (c <= '9')) ? int(c - '0') : + ((c >= 'A') && (c <= 'F')) ? int(c - 'A' + 10) : + ((c >= 'a') && (c <= 'f')) ? int(c - 'a' + 10) : /* otherwise */ -1; } @@ -76,7 +76,7 @@ Q_DECL_CONSTEXPR inline char toOct(uint value) Q_DECL_NOTHROW Q_DECL_CONSTEXPR inline int fromOct(uint c) Q_DECL_NOTHROW { - return ((c >= '0') && (c <= '7')) ? c - '0' : -1; + return ((c >= '0') && (c <= '7')) ? int(c - '0') : -1; } } diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 4a88988322..33f0409216 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2238,10 +2238,12 @@ bool QWindow::nativeEvent(const QByteArray &eventType, void *message, long *resu QPoint QWindow::mapToGlobal(const QPoint &pos) const { Q_D(const QWindow); - if (d->platformWindow && d->platformWindow->isEmbedded(0)) + // QTBUG-43252, prefer platform implementation for foreign windows. + if (d->platformWindow + && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) { return d->platformWindow->mapToGlobal(pos); - else - return pos + d_func()->globalPosition(); + } + return pos + d_func()->globalPosition(); } @@ -2256,10 +2258,12 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const QPoint QWindow::mapFromGlobal(const QPoint &pos) const { Q_D(const QWindow); - if (d->platformWindow && d->platformWindow->isEmbedded(0)) + // QTBUG-43252, prefer platform implementation for foreign windows. + if (d->platformWindow + && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) { return d->platformWindow->mapFromGlobal(pos); - else - return pos - d_func()->globalPosition(); + } + return pos - d_func()->globalPosition(); } diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 1cdbf6aa8e..1a71042648 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -152,8 +152,10 @@ static int getFontWeight(const QString &weightString) return QFont::ExtraBold; // And now the contains() checks for the translated strings. + //: The word for "Extra" as in "Extra Bold, Extra Thin" used as a pattern for string searches const QString translatedExtra = QCoreApplication::translate("QFontDatabase", "Extra").toLower(); if (s.contains(translatedBold)) { + //: The word for "Demi" as in "Demi Bold" used as a pattern for string searches QString translatedDemi = QCoreApplication::translate("QFontDatabase", "Demi").toLower(); if (s .contains(translatedDemi)) return QFont::DemiBold; diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 9aab0282d3..e22fae058f 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -510,7 +510,7 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data, int bpl, int w, int h, QPainterPath *path); -void QFreetypeFace::addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool) +void QFreetypeFace::addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path) { if (slot->format != FT_GLYPH_FORMAT_BITMAP || slot->bitmap.pixel_mode != FT_PIXEL_MODE_MONO) @@ -1430,7 +1430,7 @@ void QFontEngineFT::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyph for (int gl = 0; gl < glyphs.numGlyphs; gl++) { FT_UInt glyph = positioned_glyphs[gl]; FT_Load_Glyph(face, glyph, FT_LOAD_TARGET_MONO); - freetype->addBitmapToPath(face->glyph, positions[gl], path); + QFreetypeFace::addBitmapToPath(face->glyph, positions[gl], path); } unlockFace(); } diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 8fd5ca23af..96d0329ae6 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -102,7 +102,7 @@ public: int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints); static void addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoint &point, QPainterPath *path, FT_Fixed x_scale, FT_Fixed y_scale); - static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false); + static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path); private: friend class QFontEngineFT; diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index bd1174620c..50c264e1dc 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -64,7 +64,7 @@ public: bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE; void doneCurrent() Q_DECL_OVERRIDE; void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; - void (*getProcAddress(const QByteArray &procName)) () Q_DECL_OVERRIDE; + QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE; QSurfaceFormat format() const Q_DECL_OVERRIDE; bool isSharing() const Q_DECL_OVERRIDE { return m_shareContext != EGL_NO_CONTEXT; } diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h index 9ead6287fb..644ff7f7de 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h @@ -85,7 +85,7 @@ public: bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE; void doneCurrent() Q_DECL_OVERRIDE; void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; - void (*getProcAddress(const QByteArray &procName)) () Q_DECL_OVERRIDE; + QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE; QSurfaceFormat format() const Q_DECL_OVERRIDE; bool isSharing() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index ef74ef35f5..56adae8ffb 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1674,8 +1674,10 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, HFONT hfont = 0; hfont = CreateFontIndirect(&lf); - if (!hfont) + if (!hfont) { qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__); + hfont = QWindowsFontDatabase::systemFont(); + } bool ttf = false; int avWidth = 0; @@ -1689,18 +1691,17 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, SelectObject(data->hdc, oldObj); if (!useDirectWrite) { - if (hfont && (!ttf || request.stretch != 100)) { + if (!ttf || request.stretch != 100) { DeleteObject(hfont); if (!res) qErrnoWarning("%s: GetTextMetrics failed", __FUNCTION__); lf.lfWidth = avWidth * request.stretch/100; hfont = CreateFontIndirect(&lf); - if (!hfont) + if (!hfont) { qErrnoWarning("%s: CreateFontIndirect with stretch failed", __FUNCTION__); + hfont = QWindowsFontDatabase::systemFont(); + } } - - if (!hfont) - hfont = QWindowsFontDatabase::systemFont(); } #if !defined(QT_NO_DIRECTWRITE) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 0c294c2727..d1ea8a798f 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -41,6 +41,7 @@ #include <QtCore/QDir> #include <QtCore/QDirIterator> #include <QtCore/QSettings> +#include <QtCore/QRegularExpression> #include <QtGui/private/qfontengine_ft_p.h> #include <QtGui/QGuiApplication> #include <QtGui/QFontDatabase> @@ -101,7 +102,67 @@ static FontFile * createFontFile(const QString &fileName, int index) extern bool localizedName(const QString &name); extern QString getEnglishName(const QString &familyName); -#ifdef Q_OS_WINCE +#ifndef Q_OS_WINCE + +namespace { +struct FontKey +{ + QString fileName; + QStringList fontNames; +}; +} // namespace + +typedef QVector<FontKey> FontKeys; + +static FontKeys &fontKeys() +{ + static FontKeys result; + if (result.isEmpty()) { + const QSettings fontRegistry(QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"), + QSettings::NativeFormat); + const QStringList allKeys = fontRegistry.allKeys(); + const QString trueType = QStringLiteral("(TrueType)"); + const QRegularExpression sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+")); + Q_ASSERT(sizeListMatch.isValid()); + const int size = allKeys.size(); + result.reserve(size); + for (int i = 0; i < size; ++i) { + FontKey fontKey; + const QString ®istryFontKey = allKeys.at(i); + fontKey.fileName = fontRegistry.value(registryFontKey).toString(); + QString realKey = registryFontKey; + realKey.remove(trueType); + realKey.remove(sizeListMatch); + const QStringList fontNames = realKey.trimmed().split(QLatin1Char('&')); + fontKey.fontNames.reserve(fontNames.size()); + foreach (const QString &fontName, fontNames) + fontKey.fontNames.append(fontName.trimmed()); + result.append(fontKey); + } + } + return result; +} + +static const FontKey *findFontKey(const QString &name, int *indexIn = Q_NULLPTR) +{ + typedef FontKeys::ConstIterator ConstIt; + + const FontKeys &keys = fontKeys(); + for (ConstIt it = keys.constBegin(), cend = keys.constEnd(); it != cend; ++it) { + const int index = it->fontNames.indexOf(name); + if (index >= 0) { + if (indexIn) + *indexIn = index; + return &(*it); + } + } + if (indexIn) + *indexIn = -1; + return Q_NULLPTR; +} + +#else // Q_OS_WINCE + typedef struct { quint16 majorVersion; quint16 minorVersion; @@ -220,24 +281,67 @@ static QString fontNameFromTTFile(const QString &filename) } return retVal; } + +static inline QString fontSettingsOrganization() { return QStringLiteral("Qt-Project"); } +static inline QString fontSettingsApplication() { return QStringLiteral("Qtbase"); } +static inline QString fontSettingsGroup() { return QStringLiteral("CEFontCache"); } + +static QString findFontFile(const QString &faceName) +{ + static QHash<QString, QString> fontCache; + + if (fontCache.isEmpty()) { + QSettings settings(QSettings::SystemScope, fontSettingsOrganization(), fontSettingsApplication()); + settings.beginGroup(fontSettingsGroup()); + foreach (const QString &fontName, settings.allKeys()) + fontCache.insert(fontName, settings.value(fontName).toString()); + settings.endGroup(); + } + + QString value = fontCache.value(faceName); + + //Fallback if we haven't cached the font yet or the font got removed/renamed iterate again over all fonts + if (value.isEmpty() || !QFile::exists(value)) { + QSettings settings(QSettings::SystemScope, fontSettingsOrganization(), fontSettingsApplication()); + settings.beginGroup(fontSettingsGroup()); + + //empty the cache first, as it seems that it is dirty + settings.remove(QString()); + + QDirIterator it(QStringLiteral("/Windows"), QStringList(QStringLiteral("*.ttf")), QDir::Files | QDir::Hidden | QDir::System); + + while (it.hasNext()) { + const QString fontFile = it.next(); + const QString fontName = fontNameFromTTFile(fontFile); + if (fontName.isEmpty()) + continue; + fontCache.insert(fontName, fontFile); + settings.setValue(fontName, fontFile); + + if (localizedName(fontName)) { + QString englishFontName = getEnglishName(fontName); + fontCache.insert(englishFontName, fontFile); + settings.setValue(englishFontName, fontFile); + } + } + settings.endGroup(); + value = fontCache.value(faceName); + } + return value; +} #endif // Q_OS_WINCE -static bool addFontToDatabase(const QString &familyName, uchar charSet, +static bool addFontToDatabase(const QString &faceName, + const QString &fullName, + uchar charSet, const TEXTMETRIC *textmetric, const FONTSIGNATURE *signature, int type) { - typedef QPair<QString, QStringList> FontKey; - // the "@family" fonts are just the same as "family". Ignore them. - if (familyName.isEmpty() || familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QLatin1String("WST_"))) + if (faceName.isEmpty() || faceName.at(0) == QLatin1Char('@') || faceName.startsWith(QLatin1String("WST_"))) return false; - const int separatorPos = familyName.indexOf(QStringLiteral("::")); - const QString faceName = - separatorPos != -1 ? familyName.left(separatorPos) : familyName; - const QString fullName = - separatorPos != -1 ? familyName.mid(separatorPos + 2) : QString(); static const int SMOOTH_SCALABLE = 0xffff; const QString foundryName; // No such concept. const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; @@ -254,7 +358,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet, if (QWindowsContext::verbose > 2) { QString message; QTextStream str(&message); - str << __FUNCTION__ << ' ' << familyName << ' ' << charSet << " TTF=" << ttf; + str << __FUNCTION__ << ' ' << faceName << "::" << fullName << ' ' << charSet << " TTF=" << ttf; if (type & DEVICE_FONTTYPE) str << " DEVICE"; if (type & RASTER_FONTTYPE) @@ -297,93 +401,19 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet, writingSystems.setSupported(ws); } -#ifndef Q_OS_WINCE - const QSettings fontRegistry(QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"), - QSettings::NativeFormat); - - static QVector<FontKey> allFonts; - if (allFonts.isEmpty()) { - const QStringList allKeys = fontRegistry.allKeys(); - allFonts.reserve(allKeys.size()); - const QString trueType = QStringLiteral("(TrueType)"); - const QRegExp sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+")); - foreach (const QString &key, allKeys) { - QString realKey = key; - realKey.remove(trueType); - realKey.remove(sizeListMatch); - QStringList fonts; - const QStringList fontNames = realKey.trimmed().split(QLatin1Char('&')); - foreach (const QString &fontName, fontNames) - fonts.push_back(fontName.trimmed()); - allFonts.push_back(FontKey(key, fonts)); - } - } - - QString value; int index = 0; - for (int k = 0; k < allFonts.size(); ++k) { - const FontKey &fontKey = allFonts.at(k); - for (int i = 0; i < fontKey.second.length(); ++i) { - const QString &font = fontKey.second.at(i); - if (font == faceName || fullName == font || englishName == font) { - value = fontRegistry.value(fontKey.first).toString(); - index = i; - break; - } - } - if (!value.isEmpty()) - break; +#ifndef Q_OS_WINCE + const FontKey *key = findFontKey(faceName, &index); + if (!key) { + key = findFontKey(fullName, &index); + if (!key && !englishName.isEmpty()) + key = findFontKey(englishName, &index); + if (!key) + return false; } + QString value = key->fileName; #else - QString value; - int index = 0; - - static QHash<QString, QString> fontCache; - - if (fontCache.isEmpty()) { - QSettings settings(QSettings::SystemScope, QStringLiteral("Qt-Project"), QStringLiteral("Qtbase")); - settings.beginGroup(QStringLiteral("CEFontCache")); - - foreach (const QString &fontName, settings.allKeys()) { - const QString fontFileName = settings.value(fontName).toString(); - fontCache.insert(fontName, fontFileName); - } - - settings.endGroup(); // CEFontCache - } - - value = fontCache.value(faceName); - - //Fallback if we haven't cached the font yet or the font got removed/renamed iterate again over all fonts - if (value.isEmpty() || !QFile::exists(value)) { - QSettings settings(QSettings::SystemScope, QStringLiteral("Qt-Project"), QStringLiteral("Qtbase")); - settings.beginGroup(QStringLiteral("CEFontCache")); - - //empty the cache first, as it seems that it is dirty - foreach (const QString &fontName, settings.allKeys()) - settings.remove(fontName); - - QDirIterator it(QStringLiteral("/Windows"), QStringList(QStringLiteral("*.ttf")), QDir::Files | QDir::Hidden | QDir::System); - - while (it.hasNext()) { - const QString fontFile = it.next(); - const QString fontName = fontNameFromTTFile(fontFile); - if (fontName.isEmpty()) - continue; - fontCache.insert(fontName, fontFile); - settings.setValue(fontName, fontFile); - - if (localizedName(fontName)) { - QString englishFontName = getEnglishName(fontName); - fontCache.insert(englishFontName, fontFile); - settings.setValue(englishFontName, fontFile); - } - } - - value = fontCache.value(faceName); - - settings.endGroup(); // CEFontCache - } + QString value = findFontFile(faceName); #endif if (value.isEmpty()) @@ -440,9 +470,9 @@ static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetr int type, LPARAM namesSetIn) { typedef QSet<QString> StringSet; - const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName) - + QStringLiteral("::") - + QString::fromWCharArray(f->elfFullName); + + const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName); + const QString fullName = QString::fromWCharArray(f->elfFullName); const uchar charSet = f->elfLogFont.lfCharSet; #ifndef Q_OS_WINCE @@ -476,8 +506,10 @@ static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetr // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is // identical to a TEXTMETRIC except for the last four members, which we don't use // anyway - if (addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type)) - reinterpret_cast<StringSet *>(namesSetIn)->insert(familyName); + if (addFontToDatabase(faceName, fullName, + charSet, (TEXTMETRIC *)textmetric, &signature, type)) { + reinterpret_cast<StringSet *>(namesSetIn)->insert(faceName + QStringLiteral("::") + fullName); + } // keep on enumerating return 1; diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h index 15e11e7d0c..7725855327 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h @@ -57,7 +57,7 @@ public: bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE; void doneCurrent() Q_DECL_OVERRIDE; void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; - void (*getProcAddress(const QByteArray &procName)) () Q_DECL_OVERRIDE; + QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE; QSurfaceFormat format() const Q_DECL_OVERRIDE; bool isSharing() const Q_DECL_OVERRIDE; diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index c83c633fd0..3aa2455ff0 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -1248,6 +1248,23 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const return info; } +template <class FloatType> +inline void assignSpecialPsqlFloatValue(FloatType val, QString *target) +{ + if (isnan(val)) { + *target = QLatin1String("'NaN'"); + } else { + switch (isinf(val)) { + case 1: + *target = QLatin1String("'Infinity'"); + break; + case -1: + *target = QLatin1String("'-Infinity'"); + break; + } + } +} + QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const { Q_D(const QPSQLDriver); @@ -1255,7 +1272,7 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const if (field.isNull()) { r = QLatin1String("NULL"); } else { - switch (field.type()) { + switch (int(field.type())) { case QVariant::DateTime: #ifndef QT_NO_DATESTRING if (field.value().toDateTime().isValid()) { @@ -1305,21 +1322,16 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const qPQfreemem(data); break; } - case QVariant::Double: { - double val = field.value().toDouble(); - if (isnan(val)) - r = QLatin1String("'NaN'"); - else { - int res = isinf(val); - if (res == 1) - r = QLatin1String("'Infinity'"); - else if (res == -1) - r = QLatin1String("'-Infinity'"); - else - r = QSqlDriver::formatValue(field, trimStrings); - } + case QMetaType::Float: + assignSpecialPsqlFloatValue(field.value().toFloat(), &r); + if (r.isEmpty()) + r = QSqlDriver::formatValue(field, trimStrings); + break; + case QVariant::Double: + assignSpecialPsqlFloatValue(field.value().toDouble(), &r); + if (r.isEmpty()) + r = QSqlDriver::formatValue(field, trimStrings); break; - } default: r = QSqlDriver::formatValue(field, trimStrings); break; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index bd9a002d5b..46acbc608b 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1530,7 +1530,13 @@ static void writePluginMetaData(FILE *out, const QJsonObject &data) const QByteArray binary = doc.toBinaryData(); const int last = binary.size() - 1; for (int i = 0; i < last; ++i) { - fprintf(out, " 0x%02x,", (uchar)binary.at(i)); + uchar c = (uchar)binary.at(i); + if (c < 0x20 || c >= 0x7f) + fprintf(out, " 0x%02x,", c); + else if (c == '\'' || c == '\\') + fprintf(out, " '\\%c',", c); + else + fprintf(out, " '%c', ", c); if (!((i + 1) % 8)) fputs("\n ", out); } diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 42dee6f1f8..90242f78a2 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -1417,6 +1417,9 @@ void tst_QMetaObject::enumDebugStream() QTest::ignoreMessage(QtDebugMsg, "hello MyNamespace::MyClass::MyEnum(MyEnum2) world "); MyNamespace::MyClass::MyEnum e = MyNamespace::MyClass::MyEnum2; qDebug() << "hello" << e << "world"; + + QTest::ignoreMessage(QtDebugMsg, "Qt::WindowType(WindowTitleHint) Qt::WindowType(Window) Qt::WindowType(Desktop) Qt::WindowType(WindowSystemMenuHint)"); + qDebug() << Qt::WindowTitleHint << Qt::Window <<Qt::Desktop << Qt::WindowSystemMenuHint; } QTEST_MAIN(tst_QMetaObject) diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 9502343bd7..d2b4474dd4 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -34,6 +34,8 @@ #include <QtTest/QtTest> #include <QtSql/QtSql> +#include <numeric> + #include "../qsqldatabase/tst_databases.h" const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase())); @@ -159,6 +161,8 @@ private slots: void bindBool(); void psql_bindWithDoubleColonCastOperator_data() { generic_data("QPSQL"); } void psql_bindWithDoubleColonCastOperator(); + void psql_specialFloatValues_data() { generic_data("QPSQL"); } + void psql_specialFloatValues(); void queryOnInvalidDatabase_data() { generic_data(); } void queryOnInvalidDatabase(); void createQueryOnClosedDatabase_data() { generic_data(); } @@ -2437,6 +2441,38 @@ void tst_QSqlQuery::psql_bindWithDoubleColonCastOperator() QCOMPARE( q.executedQuery(), QString( "select sum((fld1 - fld2)::int) from " + tablename + " where id1 = 1 and id2 =2 and id3=3" ) ); } +void tst_QSqlQuery::psql_specialFloatValues() +{ + if (!std::numeric_limits<float>::has_quiet_NaN) + QSKIP("Platform does not have quiet_NaN"); + if (!std::numeric_limits<float>::has_infinity) + QSKIP("Platform does not have infinity"); + + QFETCH( QString, dbName ); + QSqlDatabase db = QSqlDatabase::database( dbName ); + + CHECK_DATABASE( db ); + QSqlQuery query(db); + const QString tableName = qTableName("floattest", __FILE__, db); + QVERIFY_SQL( query, exec("create table " + tableName + " (value float)" ) ); + QVERIFY_SQL(query, prepare("insert into " + tableName + " values(:value)") ); + + QVariantList data; + data << QVariant(double(42.42)) + << QVariant(std::numeric_limits<double>::quiet_NaN()) + << QVariant(std::numeric_limits<double>::infinity()) + << QVariant(float(42.42)) + << QVariant(std::numeric_limits<float>::quiet_NaN()) + << QVariant(std::numeric_limits<float>::infinity()); + + foreach (const QVariant &v, data) { + query.bindValue(":value", v); + QVERIFY_SQL( query, exec() ); + } + + QVERIFY_SQL( query, exec("drop table " + tableName) ); +} + /* For task 157397: Using QSqlQuery with an invalid QSqlDatabase does not set the last error of the query. This test function will output some warnings, that's ok. |