diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-02-10 16:57:11 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2015-02-10 16:57:11 +0000 |
commit | 0866680bd904aff4fe2a643a2b81c460cbb99c77 (patch) | |
tree | 242dae052199994a35f5e68578661175241a0a71 /src/gui | |
parent | 34ea269b3b173498312b0203d6875ef3b4ba0253 (diff) | |
parent | fc35f714340d5361231506dfbead132122f59460 (diff) | |
download | qtbase-0866680bd904aff4fe2a643a2b81c460cbb99c77.tar.gz |
Merge "Merge remote-tracking branch 'origin/5.4' into dev" into refs/staging/dev
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/image/qicon.cpp | 12 | ||||
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 6 | ||||
-rw-r--r-- | src/gui/itemmodels/qstandarditemmodel.cpp | 23 | ||||
-rw-r--r-- | src/gui/kernel/qdnd.cpp | 3 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 11 | ||||
-rw-r--r-- | src/gui/kernel/qplatformdrag.cpp | 12 | ||||
-rw-r--r-- | src/gui/kernel/qplatformdrag.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qscreen_p.h | 3 | ||||
-rw-r--r-- | src/gui/opengl/qopenglextensions_p.h | 27 | ||||
-rw-r--r-- | src/gui/opengl/qopenglfunctions.cpp | 99 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexturehelper.cpp | 33 | ||||
-rw-r--r-- | src/gui/opengl/qopenglvertexarrayobject.cpp | 16 | ||||
-rw-r--r-- | src/gui/painting/painting.pri | 1 | ||||
-rw-r--r-- | src/gui/painting/qfixed_p.h | 40 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qfontengine.cpp | 13 | ||||
-rw-r--r-- | src/gui/text/qtextcursor.cpp | 10 | ||||
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 5 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 17 | ||||
-rw-r--r-- | src/gui/text/qtextformat.cpp | 4 |
20 files changed, 225 insertions, 114 deletions
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 5cd9894c4c..3e27ba3efa 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -1026,13 +1026,13 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State // Check if a "@2x" file exists and add it. static bool disable2xImageLoading = !qEnvironmentVariableIsEmpty("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING"); if (!disable2xImageLoading && qApp->devicePixelRatio() > 1.0) { + QString at2xfileName = fileName; int dotIndex = fileName.lastIndexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString at2xfileName = fileName; - at2xfileName.insert(dotIndex, QStringLiteral("@2x")); - if (QFile::exists(at2xfileName)) - d->engine->addFile(at2xfileName, size, mode, state); - } + if (dotIndex == -1) /* no dot */ + dotIndex = fileName.size(); /* append */ + at2xfileName.insert(dotIndex, QStringLiteral("@2x")); + if (QFile::exists(at2xfileName)) + d->engine->addFile(at2xfileName, size, mode, state); } } diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 696f95b565..0a4bf47c82 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -2733,7 +2733,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + convert_RGBA_to_ARGB_inplace, convert_RGBA_to_ARGB_inplace, convert_RGBA_to_ARGB_inplace, 0, @@ -2756,7 +2756,6 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, convert_RGBA_to_ARGB_inplace, convert_RGBA_to_ARGB_PM_inplace, 0, @@ -2770,6 +2769,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888 { @@ -2779,7 +2779,6 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, convert_RGBA_to_ARGB_inplace, 0, 0, @@ -2792,6 +2791,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888_Premultiplied { diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 4102230e1b..c0fa01d887 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -2936,9 +2936,13 @@ QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const itemsSet.reserve(indexes.count()); stack.reserve(indexes.count()); for (int i = 0; i < indexes.count(); ++i) { - QStandardItem *item = itemFromIndex(indexes.at(i)); - itemsSet << item; - stack.push(item); + if (QStandardItem *item = itemFromIndex(indexes.at(i))) { + itemsSet << item; + stack.push(item); + } else { + qWarning() << "QStandardItemModel::mimeData: No item associated with invalid index"; + return 0; + } } //remove duplicates childrens @@ -2972,16 +2976,11 @@ QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const //stream everything recursively while (!stack.isEmpty()) { QStandardItem *item = stack.pop(); - if(itemsSet.contains(item)) { //if the item is selection 'top-level', strem its position + if (itemsSet.contains(item)) //if the item is selection 'top-level', stream its position stream << item->row() << item->column(); - } - if(item) { - stream << *item << item->columnCount() << item->d_ptr->children.count(); - stack += item->d_ptr->children; - } else { - QStandardItem dummy; - stream << dummy << 0 << 0; - } + + stream << *item << item->columnCount() << item->d_ptr->children.count(); + stack += item->d_ptr->children; } data->setData(format, encoded); diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp index f515fe18df..2a6cc4fc99 100644 --- a/src/gui/kernel/qdnd.cpp +++ b/src/gui/kernel/qdnd.cpp @@ -134,7 +134,8 @@ Qt::DropAction QDragManager::drag(QDrag *o) QGuiApplicationPrivate::instance()->notifyDragStarted(o); const Qt::DropAction result = m_platformDrag->drag(m_object); m_object = 0; - o->deleteLater(); + if (!m_platformDrag->ownsDragObject()) + o->deleteLater(); return result; } diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 92be903b41..326d9a7b52 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2572,9 +2572,14 @@ void QGuiApplicationPrivate::reportRefreshRateChange(QWindowSystemInterfacePriva return; QScreen *s = e->screen.data(); - s->d_func()->refreshRate = e->rate; - - emit s->refreshRateChanged(s->refreshRate()); + qreal rate = e->rate; + // safeguard ourselves against buggy platform behavior... + if (rate < 1.0) + rate = 60.0; + if (!qFuzzyCompare(s->d_func()->refreshRate, rate)) { + s->d_func()->refreshRate = rate; + emit s->refreshRateChanged(s->refreshRate()); + } } void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e) diff --git a/src/gui/kernel/qplatformdrag.cpp b/src/gui/kernel/qplatformdrag.cpp index 8a5c7264d1..326f092ead 100644 --- a/src/gui/kernel/qplatformdrag.cpp +++ b/src/gui/kernel/qplatformdrag.cpp @@ -241,6 +241,18 @@ QPixmap QPlatformDrag::defaultPixmap() return *qt_drag_default_pixmap(); } +/*! + \since 5.4 + \brief Returns bool indicating whether QPlatformDrag takes ownership + and therefore responsibility of deleting the QDrag object passed in + from QPlatformDrag::drag. This can be useful on platforms where QDrag + object has to be kept around. + */ +bool QPlatformDrag::ownsDragObject() const +{ + return false; +} + #endif // QT_NO_DRAGANDDROP QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformdrag.h b/src/gui/kernel/qplatformdrag.h index 34ad11e45f..ce7a9aa1f2 100644 --- a/src/gui/kernel/qplatformdrag.h +++ b/src/gui/kernel/qplatformdrag.h @@ -98,6 +98,8 @@ public: static QPixmap defaultPixmap(); + virtual bool ownsDragObject() const; + private: QPlatformDragPrivate *d_ptr; diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h index cdb923c429..53d4f3404a 100644 --- a/src/gui/kernel/qscreen_p.h +++ b/src/gui/kernel/qscreen_p.h @@ -64,6 +64,9 @@ public: availableGeometry = platformScreen->availableGeometry(); logicalDpi = platformScreen->logicalDpi(); refreshRate = platformScreen->refreshRate(); + // safeguard ourselves against buggy platform behavior... + if (refreshRate < 1.0) + refreshRate = 60.0; updatePrimaryOrientation(); diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h index 0d0cfd26ba..6c3d923b1f 100644 --- a/src/gui/opengl/qopenglextensions_p.h +++ b/src/gui/opengl/qopenglextensions_p.h @@ -46,11 +46,36 @@ // #include "qopenglfunctions.h" +#include <QtCore/qlibrary.h> QT_BEGIN_NAMESPACE class QOpenGLExtensionsPrivate; +class QOpenGLES3Helper +{ +public: + QOpenGLES3Helper(); + + GLvoid* (QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access); + GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); + void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height); + + void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); + void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); + GLboolean (QOPENGLF_APIENTRYP IsVertexArray)(GLuint array); + + void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); + void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); + +private: + QLibrary m_gl; +}; + class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLFunctions { Q_DECLARE_PRIVATE(QOpenGLExtensions) @@ -105,6 +130,8 @@ public: void glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); + QOpenGLES3Helper *gles3Helper(); + private: static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; } }; diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 99604ca8b2..d436fd45ec 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -3193,65 +3193,105 @@ static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribPointer(GLuint indx, GL #endif // !QT_OPENGL_ES_2 +// Functions part of the OpenGL ES 3.0+ standard need special handling. These, +// just like the 2.0 functions, are not guaranteed to be resolvable via +// eglGetProcAddress or similar. Calling them directly is, unlike the 2.0 +// functions, not feasible because one may build the binaries on a GLES3-capable +// system and then deploy on a GLES2-only system that does not have these +// symbols. Until ES3 gets universally available, they have to be dlsym'ed. + +Q_GLOBAL_STATIC(QOpenGLES3Helper, qgles3Helper) + +QOpenGLES3Helper::QOpenGLES3Helper() +{ +#ifdef Q_OS_WIN +#ifdef QT_DEBUG + m_gl.setFileName(QStringLiteral("libGLESv2")); +#else + m_gl.setFileName(QStringLiteral("libGLESv2d")); +#endif +#else + m_gl.setFileName(QStringLiteral("GLESv2")); +#endif + if (m_gl.load()) { + MapBufferRange = (GLvoid* (QOPENGLF_APIENTRYP)(GLenum, qopengl_GLintptr, qopengl_GLsizeiptr, GLbitfield)) m_gl.resolve("glMapBufferRange"); + UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP)(GLenum)) m_gl.resolve("glUnmapBuffer"); + BlitFramebuffer = (void (QOPENGLF_APIENTRYP)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) m_gl.resolve("glBlitFramebuffer"); + RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) m_gl.resolve("glRenderbufferStorageMultisample"); + + GenVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, GLuint *)) m_gl.resolve("glGenVertexArrays"); + DeleteVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, const GLuint *)) m_gl.resolve("glDeleteVertexArrays"); + BindVertexArray = (void (QOPENGLF_APIENTRYP)(GLuint)) m_gl.resolve("glBindVertexArray"); + IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP)(GLuint)) m_gl.resolve("glIsVertexArray"); + + TexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) m_gl.resolve("glTexImage3D"); + TexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) m_gl.resolve("glTexSubImage3D"); + CompressedTexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) m_gl.resolve("glCompressedTexImage3D"); + CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) m_gl.resolve("glCompressedTexSubImage3D"); + + if (!MapBufferRange || !GenVertexArrays || !TexImage3D) + qFatal("OpenGL ES 3.0 entry points not found"); + } else { + qFatal("Failed to load libGLESv2"); + } +} + +static inline bool isES3() +{ + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + return ctx->isOpenGLES() && ctx->format().majorVersion() >= 3; +} + static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum access) { -#ifdef QT_OPENGL_ES_3 // It is possible that GL_OES_map_buffer is present, but then having to // differentiate between glUnmapBufferOES and glUnmapBuffer causes extra // headache. QOpenGLBuffer::map() will handle this automatically, while direct // calls are better off with migrating to the standard glMapBufferRange. - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) { + if (isES3()) { qWarning("QOpenGLFunctions: glMapBuffer is not available in OpenGL ES 3.0 and up. Use glMapBufferRange instead."); return 0; - } else -#endif - RESOLVE_FUNC(GLvoid *, ResolveOES, MapBuffer)(target, access); + } else { + RESOLVE_FUNC(GLvoid *, ResolveOES, MapBuffer)(target, access); + } } static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access) { -#ifdef QT_OPENGL_ES_3 - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) - return ::glMapBufferRange(target, offset, length, access); + if (isES3()) + return qgles3Helper()->MapBufferRange(target, offset, length, access); else -#endif - RESOLVE_FUNC(GLvoid *, 0, MapBufferRange)(target, offset, length, access); + RESOLVE_FUNC(GLvoid *, 0, MapBufferRange)(target, offset, length, access); } static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target) { -#ifdef QT_OPENGL_ES_3 - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) - return ::glUnmapBuffer(target); + if (isES3()) + return qgles3Helper()->UnmapBuffer(target); else -#endif - RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target); + RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target); } static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { -#ifdef QT_OPENGL_ES_3 - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) - ::glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + if (isES3()) + qgles3Helper()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); else -#endif - RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer) - (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer) + (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) { -#ifdef QT_OPENGL_ES_3 - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) - ::glRenderbufferStorageMultisample(target, samples, internalFormat, width, height); + if (isES3()) + qgles3Helper()->RenderbufferStorageMultisample(target, samples, internalFormat, width, height); else -#endif - RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample) - (target, samples, internalFormat, width, height); + RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample) + (target, samples, internalFormat, width, height); } static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data) @@ -3506,4 +3546,9 @@ QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx) DiscardFramebuffer = qopenglfResolveDiscardFramebuffer; } +QOpenGLES3Helper *QOpenGLExtensions::gles3Helper() +{ + return qgles3Helper(); +} + QT_END_NAMESPACE diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp index 1eeab64911..d89e5d3236 100644 --- a/src/gui/opengl/qopengltexturehelper.cpp +++ b/src/gui/opengl/qopengltexturehelper.cpp @@ -34,6 +34,7 @@ #include "qopengltexturehelper_p.h" #include <QOpenGLContext> +#include <private/qopenglextensions_p.h> QT_BEGIN_NAMESPACE @@ -247,21 +248,23 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES"))); CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3DOES"))); } else { -#ifdef QT_OPENGL_ES_3 - // OpenGL ES 3.0+ has glTexImage3D. - TexImage3D = ::glTexImage3D; - TexSubImage3D = ::glTexSubImage3D; - CompressedTexImage3D = ::glCompressedTexImage3D; - CompressedTexSubImage3D = ::glCompressedTexSubImage3D; -#else - // OpenGL 1.2 - TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D"))); - TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D"))); - - // OpenGL 1.3 - CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D"))); - CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D"))); -#endif + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) { + // OpenGL ES 3.0+ has glTexImage3D. + QOpenGLES3Helper *es3 = static_cast<QOpenGLExtensions *>(ctx->functions())->gles3Helper(); + TexImage3D = es3->TexImage3D; + TexSubImage3D = es3->TexSubImage3D; + CompressedTexImage3D = es3->CompressedTexImage3D; + CompressedTexSubImage3D = es3->CompressedTexSubImage3D; + } else { + // OpenGL 1.2 + TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D"))); + TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D"))); + + // OpenGL 1.3 + CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D"))); + CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D"))); + } } #ifndef QT_OPENGL_ES_2 diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 0fc140b3ef..42bb1a3a52 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -35,12 +35,12 @@ #include <QtCore/private/qobject_p.h> #include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglfunctions.h> #include <QtGui/qoffscreensurface.h> #include <QtGui/qopenglfunctions_3_0.h> #include <QtGui/qopenglfunctions_3_2_core.h> +#include <private/qopenglextensions_p.h> #include <private/qopenglvertexarrayobject_p.h> QT_BEGIN_NAMESPACE @@ -56,16 +56,14 @@ void qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper, bool tryARB = true; if (context->isOpenGLES()) { -#ifdef QT_OPENGL_ES_3 if (context->format().majorVersion() >= 3) { - helper->GenVertexArrays = ::glGenVertexArrays; - helper->DeleteVertexArrays = ::glDeleteVertexArrays; - helper->BindVertexArray = ::glBindVertexArray; - helper->IsVertexArray = ::glIsVertexArray; + QOpenGLES3Helper *es3 = static_cast<QOpenGLExtensions *>(context->functions())->gles3Helper(); + helper->GenVertexArrays = es3->GenVertexArrays; + helper->DeleteVertexArrays = es3->DeleteVertexArrays; + helper->BindVertexArray = es3->BindVertexArray; + helper->IsVertexArray = es3->IsVertexArray; tryARB = false; - } else -#endif - if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { + } else if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES"))); helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES"))); helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES"))); diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index afc746042d..6ee1beaa3c 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -13,6 +13,7 @@ HEADERS += \ painting/qdrawhelper_x86_p.h \ painting/qdrawingprimitive_sse2_p.h \ painting/qemulationpaintengine_p.h \ + painting/qfixed_p.h \ painting/qgrayraster_p.h \ painting/qmatrix.h \ painting/qmemrotate_p.h \ diff --git a/src/gui/painting/qfixed_p.h b/src/gui/painting/qfixed_p.h index 69a7b06780..68314d0434 100644 --- a/src/gui/painting/qfixed_p.h +++ b/src/gui/painting/qfixed_p.h @@ -56,10 +56,10 @@ private: Q_DECL_CONSTEXPR QFixed(int val, int) : val(val) {} // 2nd int is just a dummy for disambiguation public: Q_DECL_CONSTEXPR QFixed() : val(0) {} - Q_DECL_CONSTEXPR QFixed(int i) : val(i<<6) {} - Q_DECL_CONSTEXPR QFixed(long i) : val(i<<6) {} - QFixed &operator=(int i) { val = (i<<6); return *this; } - QFixed &operator=(long i) { val = (i<<6); return *this; } + Q_DECL_CONSTEXPR QFixed(int i) : val(i * 64) {} + Q_DECL_CONSTEXPR QFixed(long i) : val(i * 64) {} + QFixed &operator=(int i) { val = i * 64; return *this; } + QFixed &operator=(long i) { val = i * 64; return *this; } Q_DECL_CONSTEXPR static QFixed fromReal(qreal r) { return fromFixed((int)(r*qreal(64))); } Q_DECL_CONSTEXPR static QFixed fromFixed(int fixed) { return QFixed(fixed,0); } // uses private ctor @@ -75,16 +75,16 @@ public: Q_DECL_CONSTEXPR inline QFixed floor() const { return fromFixed((val) & -64); } Q_DECL_CONSTEXPR inline QFixed ceil() const { return fromFixed((val+63) & -64); } - Q_DECL_CONSTEXPR inline QFixed operator+(int i) const { return fromFixed((val + (i<<6))); } + Q_DECL_CONSTEXPR inline QFixed operator+(int i) const { return fromFixed(val + i * 64); } Q_DECL_CONSTEXPR inline QFixed operator+(uint i) const { return fromFixed((val + (i<<6))); } Q_DECL_CONSTEXPR inline QFixed operator+(const QFixed &other) const { return fromFixed((val + other.val)); } - inline QFixed &operator+=(int i) { val += (i<<6); return *this; } + inline QFixed &operator+=(int i) { val += i * 64; return *this; } inline QFixed &operator+=(uint i) { val += (i<<6); return *this; } inline QFixed &operator+=(const QFixed &other) { val += other.val; return *this; } - Q_DECL_CONSTEXPR inline QFixed operator-(int i) const { return fromFixed((val - (i<<6))); } + Q_DECL_CONSTEXPR inline QFixed operator-(int i) const { return fromFixed(val - i * 64); } Q_DECL_CONSTEXPR inline QFixed operator-(uint i) const { return fromFixed((val - (i<<6))); } Q_DECL_CONSTEXPR inline QFixed operator-(const QFixed &other) const { return fromFixed((val - other.val)); } - inline QFixed &operator-=(int i) { val -= (i<<6); return *this; } + inline QFixed &operator-=(int i) { val -= i * 64; return *this; } inline QFixed &operator-=(uint i) { val -= (i<<6); return *this; } inline QFixed &operator-=(const QFixed &other) { val -= other.val; return *this; } Q_DECL_CONSTEXPR inline QFixed operator-() const { return fromFixed(-val); } @@ -162,18 +162,18 @@ Q_DECL_CONSTEXPR inline QFixed operator+(uint i, const QFixed &d) { return d+i; Q_DECL_CONSTEXPR inline QFixed operator-(uint i, const QFixed &d) { return -(d-i); } // Q_DECL_CONSTEXPR inline QFixed operator*(qreal d, const QFixed &d2) { return d2*d; } -Q_DECL_CONSTEXPR inline bool operator==(const QFixed &f, int i) { return f.value() == (i<<6); } -Q_DECL_CONSTEXPR inline bool operator==(int i, const QFixed &f) { return f.value() == (i<<6); } -Q_DECL_CONSTEXPR inline bool operator!=(const QFixed &f, int i) { return f.value() != (i<<6); } -Q_DECL_CONSTEXPR inline bool operator!=(int i, const QFixed &f) { return f.value() != (i<<6); } -Q_DECL_CONSTEXPR inline bool operator<=(const QFixed &f, int i) { return f.value() <= (i<<6); } -Q_DECL_CONSTEXPR inline bool operator<=(int i, const QFixed &f) { return (i<<6) <= f.value(); } -Q_DECL_CONSTEXPR inline bool operator>=(const QFixed &f, int i) { return f.value() >= (i<<6); } -Q_DECL_CONSTEXPR inline bool operator>=(int i, const QFixed &f) { return (i<<6) >= f.value(); } -Q_DECL_CONSTEXPR inline bool operator<(const QFixed &f, int i) { return f.value() < (i<<6); } -Q_DECL_CONSTEXPR inline bool operator<(int i, const QFixed &f) { return (i<<6) < f.value(); } -Q_DECL_CONSTEXPR inline bool operator>(const QFixed &f, int i) { return f.value() > (i<<6); } -Q_DECL_CONSTEXPR inline bool operator>(int i, const QFixed &f) { return (i<<6) > f.value(); } +Q_DECL_CONSTEXPR inline bool operator==(const QFixed &f, int i) { return f.value() == i * 64; } +Q_DECL_CONSTEXPR inline bool operator==(int i, const QFixed &f) { return f.value() == i * 64; } +Q_DECL_CONSTEXPR inline bool operator!=(const QFixed &f, int i) { return f.value() != i * 64; } +Q_DECL_CONSTEXPR inline bool operator!=(int i, const QFixed &f) { return f.value() != i * 64; } +Q_DECL_CONSTEXPR inline bool operator<=(const QFixed &f, int i) { return f.value() <= i * 64; } +Q_DECL_CONSTEXPR inline bool operator<=(int i, const QFixed &f) { return i * 64 <= f.value(); } +Q_DECL_CONSTEXPR inline bool operator>=(const QFixed &f, int i) { return f.value() >= i * 64; } +Q_DECL_CONSTEXPR inline bool operator>=(int i, const QFixed &f) { return i * 64 >= f.value(); } +Q_DECL_CONSTEXPR inline bool operator<(const QFixed &f, int i) { return f.value() < i * 64; } +Q_DECL_CONSTEXPR inline bool operator<(int i, const QFixed &f) { return i * 64 < f.value(); } +Q_DECL_CONSTEXPR inline bool operator>(const QFixed &f, int i) { return f.value() > i * 64; } +Q_DECL_CONSTEXPR inline bool operator>(int i, const QFixed &f) { return i * 64 > f.value(); } #ifndef QT_NO_DEBUG_STREAM inline QDebug &operator<<(QDebug &dbg, const QFixed &f) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 8dbd78cd57..01c33fc6bd 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -412,7 +412,7 @@ void QtFontFamily::ensurePopulated() return; QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamily(name); - Q_ASSERT(populated); + Q_ASSERT_X(populated, Q_FUNC_INFO, qPrintable(name)); } class QFontDatabasePrivate diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 98ab78f0dc..a9d34b1815 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -77,7 +77,12 @@ static inline bool qtransform_equals_no_translate(const QTransform &a, const QTr // Harfbuzz helper functions #ifdef QT_ENABLE_HARFBUZZ_NG -bool useHarfbuzzNG = qgetenv("QT_HARFBUZZ") != "old"; +Q_GLOBAL_STATIC_WITH_ARGS(bool, useHarfbuzzNG,(qgetenv("QT_HARFBUZZ") != "old")) + +bool qt_useHarfbuzzNG() +{ + return *useHarfbuzzNG(); +} #endif Q_STATIC_ASSERT(sizeof(HB_Glyph) == sizeof(glyph_t)); @@ -282,7 +287,7 @@ void *QFontEngine::harfbuzzFont() const { Q_ASSERT(type() != QFontEngine::Multi); #ifdef QT_ENABLE_HARFBUZZ_NG - if (useHarfbuzzNG) + if (qt_useHarfbuzzNG()) return hb_qt_font_get_for_engine(const_cast<QFontEngine *>(this)); #endif if (!font_) { @@ -318,7 +323,7 @@ void *QFontEngine::harfbuzzFace() const { Q_ASSERT(type() != QFontEngine::Multi); #ifdef QT_ENABLE_HARFBUZZ_NG - if (useHarfbuzzNG) + if (qt_useHarfbuzzNG()) return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this)); #endif if (!face_) { @@ -360,7 +365,7 @@ bool QFontEngine::supportsScript(QChar::Script script) const #endif #ifdef QT_ENABLE_HARFBUZZ_NG - if (useHarfbuzzNG) { + if (qt_useHarfbuzzNG()) { bool ret = false; if (hb_face_t *face = hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this))) { hb_tag_t script_tag_1, script_tag_2; diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 2e289e2bd8..b1205a8c85 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -910,8 +910,8 @@ QTextLayout *QTextCursorPrivate::blockLayout(QTextBlock &block) const{ select text. For selections see selectionStart(), selectionEnd(), hasSelection(), clearSelection(), and removeSelectedText(). - If the position() is at the start of a block atBlockStart() - returns \c true; and if it is at the end of a block atBlockEnd() returns + If the position() is at the start of a block, atBlockStart() + returns \c true; and if it is at the end of a block, atBlockEnd() returns true. The format of the current character is returned by charFormat(), and the format of the current block is returned by blockFormat(). @@ -921,9 +921,9 @@ QTextLayout *QTextCursorPrivate::blockLayout(QTextBlock &block) const{ mergeBlockFormat() functions. The 'set' functions will replace the cursor's current character or block format, while the 'merge' functions add the given format properties to the cursor's current - format. If the cursor has a selection the given format is applied - to the current selection. Note that when only parts of a block is - selected the block format is applied to the entire block. The text + format. If the cursor has a selection, the given format is applied + to the current selection. Note that when only a part of a block is + selected, the block format is applied to the entire block. The text at the current character position can be turned into a list using createList(). diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index bd5877c924..91e01ffbb1 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1172,7 +1172,7 @@ QString QTextDocument::toPlainText() const /*! Replaces the entire contents of the document with the given plain - \a text. + \a text. The undo/redo history is reset when this function is called. \sa setHtml() */ @@ -1190,7 +1190,8 @@ void QTextDocument::setPlainText(const QString &text) /*! Replaces the entire contents of the document with the given - HTML-formatted text in the \a html string. + HTML-formatted text in the \a html string. The undo/redo history + is reset when this function is called. The HTML formatting is respected as much as possible; for example, "<b>bold</b> text" will produce text where the first word has a font diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index d6e9172e60..48e0550a61 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -938,7 +938,7 @@ void QTextEngine::shapeLine(const QScriptLine &line) } #ifdef QT_ENABLE_HARFBUZZ_NG -extern bool useHarfbuzzNG; // defined in qfontengine.cpp +extern bool qt_useHarfbuzzNG(); // defined in qfontengine.cpp #endif void QTextEngine::shapeText(int item) const @@ -1051,7 +1051,7 @@ void QTextEngine::shapeText(int item) const } #ifdef QT_ENABLE_HARFBUZZ_NG - if (Q_LIKELY(useHarfbuzzNG)) + if (Q_LIKELY(qt_useHarfbuzzNG())) si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled); else #endif @@ -1067,7 +1067,7 @@ void QTextEngine::shapeText(int item) const QGlyphLayout glyphs = shapedGlyphs(&si); #ifdef QT_ENABLE_HARFBUZZ_NG - if (Q_LIKELY(useHarfbuzzNG)) + if (Q_LIKELY(qt_useHarfbuzzNG())) qt_getJustificationOpportunities(string, itemLength, si, glyphs, logClusters(&si)); #endif @@ -1234,6 +1234,15 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st } #ifdef Q_OS_MAC + // CTRunGetPosition has a bug which applies matrix on 10.6, so we disable + // scaling the advances for this particular version + if (actualFontEngine->fontDef.stretch != 100 + && QSysInfo::MacintoshVersion != QSysInfo::MV_10_6) { + QFixed stretch = QFixed(actualFontEngine->fontDef.stretch) / QFixed(100); + for (uint i = 0; i < num_glyphs; ++i) + g.advances[i] *= stretch; + } + if (actualFontEngine->fontDef.styleStrategy & QFont::ForceIntegerMetrics) { for (uint i = 0; i < num_glyphs; ++i) g.advances[i] = g.advances[i].round(); @@ -1604,7 +1613,7 @@ void QTextEngine::itemize() const } #ifdef QT_ENABLE_HARFBUZZ_NG analysis = scriptAnalysis.data(); - if (useHarfbuzzNG) { + if (qt_useHarfbuzzNG()) { // ### pretend HB-old behavior for now for (int i = 0; i < length; ++i) { switch (analysis[i].script) { diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index ab4b10522a..6d779d089d 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -1890,7 +1890,7 @@ void QTextCharFormat::setFont(const QFont &font) If \a behavior is QTextCharFormat::FontPropertiesAll, the font property that has not been explicitly set is treated like as it were set with default value; - If \a behavior is QTextCharFormat::FontPropertiesAll, the font property that + If \a behavior is QTextCharFormat::FontPropertiesSpecifiedOnly, the font property that has not been explicitly set is ignored and the respective property value remains unchanged. @@ -1928,7 +1928,7 @@ void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavi setFontFixedPitch(font.fixedPitch()); if (mask & QFont::CapitalizationResolved) setFontCapitalization(font.capitalization()); - if (mask & QFont::LetterSpacingResolved) + if (mask & QFont::WordSpacingResolved) setFontWordSpacing(font.wordSpacing()); if (mask & QFont::LetterSpacingResolved) { setFontLetterSpacingType(font.letterSpacingType()); |