Merge remote-tracking branch 'origin/5.6.0' into 5.6

Change-Id: I0b190005377a23a91da3563428e223b8a3b18333
This commit is contained in:
Liang Qi 2016-02-15 08:09:50 +01:00
commit 80bf4bfe3d
58 changed files with 339 additions and 132 deletions

2
configure vendored
View File

@ -2854,7 +2854,7 @@ if [ -z "$PLATFORM" ]; then
PLATFORM=ultrix-g++ PLATFORM=ultrix-g++
;; ;;
FreeBSD:*) FreeBSD:*)
PLATFORM=freebsd-g++ PLATFORM=freebsd-clang
PLATFORM_NOTES=" PLATFORM_NOTES="
- Also available for FreeBSD: freebsd-icc - Also available for FreeBSD: freebsd-icc
" "

View File

@ -194,7 +194,7 @@ equals(QT_ARCH, i386):contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):compiler_support
android: CONFIG += qt_android_deps no_linker_version_script android: CONFIG += qt_android_deps no_linker_version_script
!header_module:unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static { !header_module:unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static {
verscript = $$OUT_PWD/$${TARGET}.version verscript = $${TARGET}.version
QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript
internal_module { internal_module {
@ -219,16 +219,20 @@ android: CONFIG += qt_android_deps no_linker_version_script
} }
# Add a post-processing step to replace the @FILE:filename@ # Add a post-processing step to replace the @FILE:filename@
verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < $${verscript}.in > $@ verscript_in = $${verscript}.in
verscriptprocess.target = $$verscript verscriptprocess.name = linker version script ${QMAKE_FILE_BASE}
verscriptprocess.input = verscript_in
verscriptprocess.CONFIG += no_link target_predeps
for(header, SYNCQT.PRIVATE_HEADER_FILES): \ for(header, SYNCQT.PRIVATE_HEADER_FILES): \
verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header
verscriptprocess.depends += $${verscript}.in verscriptprocess.output = $$verscript
QMAKE_EXTRA_TARGETS += verscriptprocess verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < ${QMAKE_FILE_IN} > $@
PRE_TARGETDEPS += $$verscript silent:verscriptprocess.commands = @echo creating linker version script ${QMAKE_FILE_BASE} && $$verscriptprocess.commands
verscript = $${verscript}.in QMAKE_EXTRA_COMPILERS += verscriptprocess
verscript = $$verscript_in
} }
write_file($$verscript, verscript_content)|error("Aborting.") write_file($$OUT_PWD/$$verscript, verscript_content)|error("Aborting.")
unset(current) unset(current)
unset(previous) unset(previous)
unset(verscript) unset(verscript)

View File

@ -49,9 +49,15 @@ for(resource, RESOURCES) {
for(file, $${resource}.files) { for(file, $${resource}.files) {
abs_path = $$absolute_path($$file, $$_PRO_FILE_PWD_) abs_path = $$absolute_path($$file, $$_PRO_FILE_PWD_)
alias = $$relative_path($$abs_path, $$abs_base) files = $$files($$abs_path/*, true)
resource_file_content += \ isEmpty(files): \
"<file alias=\"$$xml_escape($$alias)\">$$xml_escape($$abs_path)</file>" files = $$abs_path
for (file, files) {
exists($$file/*): next() # exclude directories
alias = $$relative_path($$file, $$abs_base)
resource_file_content += \
"<file alias=\"$$xml_escape($$alias)\">$$xml_escape($$file)</file>"
}
} }
resource_file_content += \ resource_file_content += \

View File

@ -30,7 +30,7 @@ QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P QMAKE_NM = nm -P
QMAKE_RANLIB = QMAKE_RANLIB =
include(../../common/gcc-base-unix.conf) include(../common/gcc-base-unix.conf)
include(../../common/clang.conf) include(../common/clang.conf)
load(qt_config) load(qt_config)

View File

@ -5,7 +5,7 @@
MAKEFILE_GENERATOR = UNIX MAKEFILE_GENERATOR = UNIX
QMAKE_PLATFORM = freebsd bsd QMAKE_PLATFORM = freebsd bsd
include(../common/unix.conf) include(../../common/unix.conf)
QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE
@ -29,6 +29,6 @@ QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P QMAKE_NM = nm -P
QMAKE_RANLIB = QMAKE_RANLIB =
include(../common/gcc-base-unix.conf) include(../../common/gcc-base-unix.conf)
include(../common/g++-unix.conf) include(../../common/g++-unix.conf)
load(qt_config) load(qt_config)

View File

@ -31,4 +31,4 @@
** **
****************************************************************************/ ****************************************************************************/
#include "../../freebsd-g++/qplatformdefs.h" #include "../../freebsd-clang/qplatformdefs.h"

View File

@ -5,7 +5,7 @@
MAKEFILE_GENERATOR = UNIX MAKEFILE_GENERATOR = UNIX
QMAKE_PLATFORM = freebsd bsd QMAKE_PLATFORM = freebsd bsd
include(../common/unix.conf) include(../../common/unix.conf)
QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE
@ -29,8 +29,8 @@ QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P QMAKE_NM = nm -P
QMAKE_RANLIB = QMAKE_RANLIB =
include(../common/gcc-base-unix.conf) include(../../common/gcc-base-unix.conf)
include(../common/g++-unix.conf) include(../../common/g++-unix.conf)
# Redefined here because g++-base.conf sets QMAKE_CC and QMAKE_CXX # Redefined here because g++-base.conf sets QMAKE_CC and QMAKE_CXX
# to gcc and g++, respectively. # to gcc and g++, respectively.

View File

@ -31,4 +31,4 @@
** **
****************************************************************************/ ****************************************************************************/
#include "../freebsd-g++/qplatformdefs.h" #include "../../freebsd-clang/qplatformdefs.h"

View File

@ -27,6 +27,10 @@ ANDROID_PERMISSIONS = \
android.permission.INTERNET \ android.permission.INTERNET \
android.permission.WRITE_EXTERNAL_STORAGE android.permission.WRITE_EXTERNAL_STORAGE
# QtCore can't be compiled with -Wl,-no-undefined because it uses the "environ"
# variable and on FreeBSD, this variable is in the final executable itself
freebsd: QMAKE_LFLAGS_NOUNDEF =
load(qt_module) load(qt_module)
load(qfeatures) load(qfeatures)

View File

@ -59,11 +59,7 @@ QT_BEGIN_NAMESPACE
#elif defined(Q_CC_GNU) && !defined(Q_OS_ANDROID) #elif defined(Q_CC_GNU) && !defined(Q_OS_ANDROID)
# if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL)) # if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL))
# if defined(Q_PROCESSOR_X86_64) // x86-64 or x32 # if defined(Q_PROCESSOR_X86_64) // x86-64 or x32
# if defined(__code_model_large__) # define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
# else
# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOTPCREL\n"
# endif
# else // x86 # else // x86
# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" # define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
# endif # endif

View File

@ -935,9 +935,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
{ {
Q_ASSERT(notifier); Q_ASSERT(notifier);
int sockfd = notifier->socket();
int type = notifier->type();
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
int sockfd = notifier->socket();
if (sockfd < 0) { if (sockfd < 0) {
qWarning("QSocketNotifier: Internal error"); qWarning("QSocketNotifier: Internal error");
return; return;
@ -946,8 +945,16 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
return; return;
} }
#endif #endif
doUnregisterSocketNotifier(notifier);
}
void QEventDispatcherWin32::doUnregisterSocketNotifier(QSocketNotifier *notifier)
{
Q_D(QEventDispatcherWin32); Q_D(QEventDispatcherWin32);
int type = notifier->type();
int sockfd = notifier->socket();
Q_ASSERT(sockfd >= 0);
QSFDict::iterator it = d->active_fd.find(sockfd); QSFDict::iterator it = d->active_fd.find(sockfd);
if (it != d->active_fd.end()) { if (it != d->active_fd.end()) {
QSockFd &sd = it.value(); QSockFd &sd = it.value();
@ -1203,11 +1210,11 @@ void QEventDispatcherWin32::closingDown()
// clean up any socketnotifiers // clean up any socketnotifiers
while (!d->sn_read.isEmpty()) while (!d->sn_read.isEmpty())
unregisterSocketNotifier((*(d->sn_read.begin()))->obj); doUnregisterSocketNotifier((*(d->sn_read.begin()))->obj);
while (!d->sn_write.isEmpty()) while (!d->sn_write.isEmpty())
unregisterSocketNotifier((*(d->sn_write.begin()))->obj); doUnregisterSocketNotifier((*(d->sn_write.begin()))->obj);
while (!d->sn_except.isEmpty()) while (!d->sn_except.isEmpty())
unregisterSocketNotifier((*(d->sn_except.begin()))->obj); doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj);
Q_ASSERT(d->active_fd.isEmpty()); Q_ASSERT(d->active_fd.isEmpty());
// clean up any timers // clean up any timers

View File

@ -103,6 +103,7 @@ public:
protected: protected:
QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0); QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0);
virtual void sendPostedEvents(); virtual void sendPostedEvents();
void doUnregisterSocketNotifier(QSocketNotifier *notifier);
private: private:
friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);

View File

@ -36,7 +36,7 @@
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
#include <QtCore/qatomic.h> #include <QtCore/qatomic.h>
#if QT_DEPRECATED_SINCE(5, 5) #if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#endif #endif
#include <QtCore/qhashfunctions.h> #include <QtCore/qhashfunctions.h>

View File

@ -55,7 +55,7 @@ QT_END_NAMESPACE
#include <new> #include <new>
#include <QtCore/qatomic.h> #include <QtCore/qatomic.h>
#include <QtCore/qobject.h> // for qobject_cast #include <QtCore/qobject.h> // for qobject_cast
#if QT_DEPRECATED_SINCE(5, 5) #if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#endif #endif
#include <QtCore/qhashfunctions.h> #include <QtCore/qhashfunctions.h>

View File

@ -43,6 +43,10 @@
#include <QtDBus/qdbusextratypes.h> #include <QtDBus/qdbusextratypes.h>
#include <QtDBus/qdbusconnection.h> #include <QtDBus/qdbusconnection.h>
#ifdef interface
#undef interface
#endif
#ifndef QT_NO_DBUS #ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -54,6 +54,10 @@
#include <algorithm> #include <algorithm>
#ifdef interface
#undef interface
#endif
#ifndef QT_NO_DBUS #ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -39,7 +39,7 @@
#include <QtCore/qvariant.h> #include <QtCore/qvariant.h>
#include <QtCore/qstring.h> #include <QtCore/qstring.h>
#include <QtDBus/qdbusmacros.h> #include <QtDBus/qdbusmacros.h>
#if QT_DEPRECATED_SINCE(5, 5) #if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#endif #endif
#include <QtCore/qhashfunctions.h> #include <QtCore/qhashfunctions.h>

View File

@ -63,6 +63,9 @@
#include "qdbusthreaddebug_p.h" #include "qdbusthreaddebug_p.h"
#include <algorithm> #include <algorithm>
#ifdef interface
#undef interface
#endif
#ifndef QT_NO_DBUS #ifndef QT_NO_DBUS

View File

@ -294,7 +294,7 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
if (depth != 32) { if (depth != 32) {
ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits; ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
if (ncols > 256) // sanity check - don't run out of mem if color table is broken if (ncols < 1 || ncols > 256) // sanity check - don't run out of mem if color table is broken
return false; return false;
image.setColorCount(ncols); image.setColorCount(ncols);
} }

View File

@ -189,6 +189,12 @@ inline QImage::Format qt_alphaVersion(QImage::Format format)
return QImage::Format_ARGB32_Premultiplied; return QImage::Format_ARGB32_Premultiplied;
} }
inline QImage::Format qt_maybeAlphaVersionWithSameDepth(QImage::Format format)
{
const QImage::Format toFormat = qt_alphaVersion(format);
return qt_depthForFormat(format) == qt_depthForFormat(toFormat) ? toFormat : format;
}
inline QImage::Format qt_alphaVersionForPainting(QImage::Format format) inline QImage::Format qt_alphaVersionForPainting(QImage::Format format)
{ {
QImage::Format toFormat = qt_alphaVersion(format); QImage::Format toFormat = qt_alphaVersion(format);

View File

@ -47,6 +47,7 @@
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
#include <QtCore/qmargins.h> #include <QtCore/qmargins.h>
#include <QtCore/qmath.h>
#include <QtCore/qrect.h> #include <QtCore/qrect.h>
#include <QtCore/qvector.h> #include <QtCore/qvector.h>
#include <QtCore/qloggingcategory.h> #include <QtCore/qloggingcategory.h>
@ -382,6 +383,24 @@ inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *
return pointRegion; return pointRegion;
} }
// When mapping expose events to Qt rects: round top/left towards the origin and
// bottom/right away from the origin, making sure that we cover the whole window.
inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QWindow *window)
{
if (!QHighDpiScaling::isActive())
return pixelRegion;
const qreal scaleFactor = QHighDpiScaling::factor(window);
QRegion pointRegion;
foreach (const QRect &rect, pixelRegion.rects()) {
const QPointF topLeftP = QPointF(rect.topLeft()) / scaleFactor;
const QPointF bottomRightP = QPointF(rect.bottomRight()) / scaleFactor;
pointRegion += QRect(QPoint(qFloor(topLeftP.x()), qFloor(topLeftP.y())),
QPoint(qCeil(bottomRightP.x()), qCeil(bottomRightP.y())));
}
return pointRegion;
}
inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window) inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
{ {
if (!QHighDpiScaling::isActive()) if (!QHighDpiScaling::isActive())
@ -498,6 +517,8 @@ namespace QHighDpi {
template <typename T> inline template <typename T> inline
T fromNativeLocalRegion(const T &value, ...) { return value; } T fromNativeLocalRegion(const T &value, ...) { return value; }
template <typename T> inline template <typename T> inline
T fromNativeLocalExposedRegion(const T &value, ...) { return value; }
template <typename T> inline
T toNativeLocalRegion(const T &value, ...) { return value; } T toNativeLocalRegion(const T &value, ...) { return value; }
template <typename T> inline template <typename T> inline

View File

@ -54,7 +54,7 @@
#include <QtGui/qopengl.h> #include <QtGui/qopengl.h>
#include <QtGui/qopenglversionfunctions.h> #include <QtGui/qopenglversionfunctions.h>
#if QT_DEPRECATED_SINCE(5, 5) #if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#endif #endif
#include <QtCore/qhashfunctions.h> #include <QtCore/qhashfunctions.h>

View File

@ -582,7 +582,8 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region) void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region)
{ {
QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw)); QWindowSystemInterfacePrivate::ExposeEvent *e =
new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalExposedRegion(region, tlw));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
} }
@ -868,7 +869,7 @@ Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::Keybo
QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous);
} }
Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1)
{ {
#ifndef QT_NO_SHORTCUT #ifndef QT_NO_SHORTCUT

View File

@ -47,7 +47,7 @@
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
#if QT_DEPRECATED_SINCE(5, 5) #if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h> #include <QtCore/qhash.h>
#endif #endif
#include <QtCore/qhashfunctions.h> #include <QtCore/qhashfunctions.h>

View File

@ -106,7 +106,8 @@ void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &off
} }
#endif #endif
d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, d_ptr->window), offset); d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, win),
QHighDpi::toNativeLocalPosition(offset, win));
} }
/*! /*!

View File

@ -263,12 +263,14 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect, static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
QOpenGLTextureBlitter *blitter, const QPoint &offset) QOpenGLTextureBlitter *blitter, const QPoint &offset)
{ {
const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
return;
QRect rectInWindow = textures->geometry(idx); QRect rectInWindow = textures->geometry(idx);
// relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust // relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust
rectInWindow.translate(-offset); rectInWindow.translate(-offset);
QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
clipRect = QRect(QPoint(0, 0), rectInWindow.size());
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
@ -514,7 +516,23 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
if (needsConversion) if (needsConversion)
image = image.convertToFormat(QImage::Format_RGBA8888); image = image.convertToFormat(QImage::Format_RGBA8888);
// The image provided by the backingstore may have a stride larger than width * 4, for
// instance on platforms that manually implement client-side decorations.
static const int bytesPerPixel = 4;
const int strideInPixels = image.bytesPerLine() / bytesPerPixel;
const bool hasUnpackRowLength = !ctx->isOpenGLES() || ctx->format().majorVersion() >= 3;
QOpenGLFunctions *funcs = ctx->functions(); QOpenGLFunctions *funcs = ctx->functions();
if (hasUnpackRowLength) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, strideInPixels);
} else if (strideInPixels != image.width()) {
// No UNPACK_ROW_LENGTH on ES 2.0 and yet we would need it. This case is typically
// hit with QtWayland which is rarely used in combination with a ES2.0-only GL
// implementation. Therefore, accept the performance hit and do a copy.
image = image.copy();
}
if (resized) { if (resized) {
if (d_ptr->textureId) if (d_ptr->textureId)
funcs->glDeleteTextures(1, &d_ptr->textureId); funcs->glDeleteTextures(1, &d_ptr->textureId);
@ -536,11 +554,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
QRect imageRect = image.rect(); QRect imageRect = image.rect();
QRect rect = dirtyRegion.boundingRect() & imageRect; QRect rect = dirtyRegion.boundingRect() & imageRect;
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { if (hasUnpackRowLength) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()) + rect.x() * 4); image.constScanLine(rect.y()) + rect.x() * bytesPerPixel);
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} else { } else {
// if the rect is wide enough it's cheaper to just // if the rect is wide enough it's cheaper to just
// extend it instead of doing an image copy // extend it instead of doing an image copy
@ -562,6 +578,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
} }
} }
if (hasUnpackRowLength)
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
return d_ptr->textureId; return d_ptr->textureId;
} }
#endif // QT_NO_OPENGL #endif // QT_NO_OPENGL

View File

@ -1255,7 +1255,7 @@ QFixed QFontEngineFT::xHeight() const
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
if (os2 && os2->sxHeight) { if (os2 && os2->sxHeight) {
lockFace(); lockFace();
QFixed answer = QFixed(os2->sxHeight*freetype->face->size->metrics.y_ppem)/freetype->face->units_per_EM; QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize();
unlockFace(); unlockFace();
return answer; return answer;
} }
@ -1267,7 +1267,7 @@ QFixed QFontEngineFT::averageCharWidth() const
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
if (os2 && os2->xAvgCharWidth) { if (os2 && os2->xAvgCharWidth) {
lockFace(); lockFace();
QFixed answer = QFixed(os2->xAvgCharWidth*freetype->face->size->metrics.x_ppem)/freetype->face->units_per_EM; QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize();
unlockFace(); unlockFace();
return answer; return answer;
} }
@ -1295,7 +1295,7 @@ void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) c
kerning_pairs_loaded = true; kerning_pairs_loaded = true;
lockFace(); lockFace();
if (freetype->face->size->metrics.x_ppem != 0) { if (freetype->face->size->metrics.x_ppem != 0) {
QFixed scalingFactor(freetype->face->units_per_EM/freetype->face->size->metrics.x_ppem); QFixed scalingFactor = emSquareSize() / QFixed(freetype->face->size->metrics.x_ppem);
unlockFace(); unlockFace();
const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor); const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor);
} else { } else {

View File

@ -1072,8 +1072,8 @@ QTextCursor::QTextCursor(const QTextBlock &block)
/*! /*!
\internal \internal
*/ */
QTextCursor::QTextCursor(QTextDocumentPrivate &p, int pos) QTextCursor::QTextCursor(QTextDocumentPrivate *p, int pos)
: d(new QTextCursorPrivate(&p)) : d(new QTextCursorPrivate(p))
{ {
d->adjusted_anchor = d->anchor = d->position = pos; d->adjusted_anchor = d->anchor = d->position = pos;

View File

@ -61,6 +61,8 @@ class Q_GUI_EXPORT QTextCursor
public: public:
QTextCursor(); QTextCursor();
explicit QTextCursor(QTextDocument *document); explicit QTextCursor(QTextDocument *document);
QTextCursor(QTextDocumentPrivate *p, int pos);
explicit QTextCursor(QTextCursorPrivate *d);
explicit QTextCursor(QTextFrame *frame); explicit QTextCursor(QTextFrame *frame);
explicit QTextCursor(const QTextBlock &block); explicit QTextCursor(const QTextBlock &block);
QTextCursor(const QTextCursor &cursor); QTextCursor(const QTextCursor &cursor);
@ -219,9 +221,6 @@ public:
QTextDocument *document() const; QTextDocument *document() const;
private: private:
QTextCursor(QTextDocumentPrivate &p, int pos);
explicit QTextCursor(QTextCursorPrivate *d);
QSharedDataPointer<QTextCursorPrivate> d; QSharedDataPointer<QTextCursorPrivate> d;
friend class QTextCursorPrivate; friend class QTextCursorPrivate;
friend class QTextDocumentPrivate; friend class QTextDocumentPrivate;

View File

@ -101,7 +101,7 @@ public:
void aboutToRemoveCell(int from, int to); void aboutToRemoveCell(int from, int to);
static QTextCursor fromPosition(QTextDocumentPrivate *d, int pos) static QTextCursor fromPosition(QTextDocumentPrivate *d, int pos)
{ return QTextCursor(*d, pos); } { return QTextCursor(d, pos); }
QTextDocumentPrivate *priv; QTextDocumentPrivate *priv;
qreal x; qreal x;

View File

@ -1704,7 +1704,7 @@ bool QTextDocumentPrivate::ensureMaximumBlockCount()
beginEditBlock(); beginEditBlock();
const int blocksToRemove = blocks.numNodes() - maximumBlockCount; const int blocksToRemove = blocks.numNodes() - maximumBlockCount;
QTextCursor cursor(*this, 0); QTextCursor cursor(this, 0);
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, blocksToRemove); cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, blocksToRemove);
unreachableCharacterCount += cursor.selectionEnd() - cursor.selectionStart(); unreachableCharacterCount += cursor.selectionEnd() - cursor.selectionStart();

View File

@ -1058,12 +1058,15 @@ QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const
QVector<quint32> indexes = oldGlyphRun.glyphIndexes(); QVector<quint32> indexes = oldGlyphRun.glyphIndexes();
QVector<QPointF> positions = oldGlyphRun.positions(); QVector<QPointF> positions = oldGlyphRun.positions();
QRectF boundingRect = oldGlyphRun.boundingRect();
indexes += glyphRun.glyphIndexes(); indexes += glyphRun.glyphIndexes();
positions += glyphRun.positions(); positions += glyphRun.positions();
boundingRect = boundingRect.united(glyphRun.boundingRect());
oldGlyphRun.setGlyphIndexes(indexes); oldGlyphRun.setGlyphIndexes(indexes);
oldGlyphRun.setPositions(positions); oldGlyphRun.setPositions(positions);
oldGlyphRun.setBoundingRect(boundingRect);
} else { } else {
glyphRunHash[key] = glyphRun; glyphRunHash[key] = glyphRun;
} }

View File

@ -37,7 +37,7 @@
#include <QtCore/QtGlobal> #include <QtCore/QtGlobal>
#include <QtCore/QString> #include <QtCore/QString>
#include <QtCore/QMetaType> #include <QtCore/QMetaType>
#if QT_DEPRECATED_SINCE(5, 5) #if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/QHash> #include <QtCore/QHash>
#endif #endif
#include <QtCore/qhashfunctions.h> #include <QtCore/qhashfunctions.h>

View File

@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
It is up to the platform plugin to manage the lifetime of the It is up to the platform plugin to manage the lifetime of the
compositor (instance(), destroy()), set the correct destination compositor (instance(), destroy()), set the correct destination
context and window as early as possible (setTargetWindow()), context and window as early as possible (setTarget()),
register the composited windows as they are shown, activated, register the composited windows as they are shown, activated,
raised and lowered (addWindow(), moveToTop(), etc.), and to raised and lowered (addWindow(), moveToTop(), etc.), and to
schedule repaints (update()). schedule repaints (update()).
@ -177,11 +177,11 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter) static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter)
{ {
const QRect rectInWindow = textures->geometry(idx); const QRect clipRect = textures->clipRect(idx);
QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty()) if (clipRect.isEmpty())
clipRect = QRect(QPoint(0, 0), rectInWindow.size()); return;
const QRect rectInWindow = textures->geometry(idx);
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());

View File

@ -34,6 +34,7 @@
#include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLContext>
#include <QtGui/QWindow> #include <QtGui/QWindow>
#include <QtGui/QPainter> #include <QtGui/QPainter>
#include <QtGui/QOffscreenSurface>
#include <qpa/qplatformbackingstore.h> #include <qpa/qplatformbackingstore.h>
#include <private/qwindow_p.h> #include <private/qwindow_p.h>
@ -82,13 +83,28 @@ QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore()
{ {
if (m_bsTexture) { if (m_bsTexture) {
QOpenGLContext *ctx = QOpenGLContext::currentContext(); QOpenGLContext *ctx = QOpenGLContext::currentContext();
// With render-to-texture-widgets QWidget makes sure the TLW's shareContext() is
// made current before destroying backingstores. That is however not the case for
// windows with regular widgets only.
QScopedPointer<QOffscreenSurface> tempSurface;
if (!ctx) {
ctx = QOpenGLCompositor::instance()->context();
tempSurface.reset(new QOffscreenSurface);
tempSurface->setFormat(ctx->format());
tempSurface->create();
ctx->makeCurrent(tempSurface.data());
}
if (ctx && m_bsTextureContext && ctx->shareGroup() == m_bsTextureContext->shareGroup()) if (ctx && m_bsTextureContext && ctx->shareGroup() == m_bsTextureContext->shareGroup())
glDeleteTextures(1, &m_bsTexture); glDeleteTextures(1, &m_bsTexture);
else else
qWarning("QOpenGLCompositorBackingStore: Texture is not valid in the current context"); qWarning("QOpenGLCompositorBackingStore: Texture is not valid in the current context");
if (tempSurface)
ctx->doneCurrent();
} }
delete m_textures; delete m_textures; // this does not actually own any GL resources
} }
QPaintDevice *QOpenGLCompositorBackingStore::paintDevice() QPaintDevice *QOpenGLCompositorBackingStore::paintDevice()
@ -158,16 +174,15 @@ void QOpenGLCompositorBackingStore::updateTexture()
void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset) void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{ {
// Called for ordinary raster windows. This is rare since RasterGLSurface // Called for ordinary raster windows.
// support is claimed which leads to having all QWidget windows marked as
// RasterGLSurface instead of just Raster. These go through
// compositeAndFlush() instead of this function.
Q_UNUSED(region); Q_UNUSED(region);
Q_UNUSED(offset); Q_UNUSED(offset);
QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
QOpenGLContext *dstCtx = compositor->context(); QOpenGLContext *dstCtx = compositor->context();
Q_ASSERT(dstCtx);
QWindow *dstWin = compositor->targetWindow(); QWindow *dstWin = compositor->targetWindow();
if (!dstWin) if (!dstWin)
return; return;
@ -184,7 +199,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi
QPlatformTextureList *textures, QOpenGLContext *context, QPlatformTextureList *textures, QOpenGLContext *context,
bool translucentBackground) bool translucentBackground)
{ {
// QOpenGLWidget/QQuickWidget content provided as textures. The raster content should go on top. // QOpenGLWidget/QQuickWidget content provided as textures. The raster content goes on top.
Q_UNUSED(region); Q_UNUSED(region);
Q_UNUSED(offset); Q_UNUSED(offset);
@ -193,6 +208,12 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi
QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
QOpenGLContext *dstCtx = compositor->context(); QOpenGLContext *dstCtx = compositor->context();
Q_ASSERT(dstCtx); // setTarget() must have been called before, e.g. from QEGLFSWindow
// The compositor's context and the context to which QOpenGLWidget/QQuickWidget
// textures belong are not the same. They share resources, though.
Q_ASSERT(context->shareGroup() == dstCtx->shareGroup());
QWindow *dstWin = compositor->targetWindow(); QWindow *dstWin = compositor->targetWindow();
if (!dstWin) if (!dstWin)
return; return;
@ -254,6 +275,7 @@ void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &sta
if (m_bsTexture) { if (m_bsTexture) {
glDeleteTextures(1, &m_bsTexture); glDeleteTextures(1, &m_bsTexture);
m_bsTexture = 0; m_bsTexture = 0;
m_bsTextureContext = Q_NULLPTR;
} }
} }

View File

@ -51,7 +51,7 @@ QCocoaAccessibility::~QCocoaAccessibility()
void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
{ {
if (!isActive() || !event->accessibleInterface()) if (!isActive() || !event->accessibleInterface() || !event->accessibleInterface()->isValid())
return; return;
QMacAccessibilityElement *element = [QMacAccessibilityElement elementWithId: event->uniqueId()]; QMacAccessibilityElement *element = [QMacAccessibilityElement elementWithId: event->uniqueId()];
if (!element) { if (!element) {

View File

@ -120,7 +120,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
if (!element) { if (!element) {
QAccessibleInterface *iface = QAccessible::accessibleInterface(anId); QAccessibleInterface *iface = QAccessible::accessibleInterface(anId);
Q_ASSERT(iface); Q_ASSERT(iface);
if (!iface) if (!iface || !iface->isValid())
return nil; return nil;
element = [[self alloc] initWithId:anId]; element = [[self alloc] initWithId:anId];
cache->insertElement(anId, element); cache->insertElement(anId, element);
@ -172,7 +172,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
static NSArray *defaultAttributes = nil; static NSArray *defaultAttributes = nil;
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) if (!iface || !iface->isValid())
return defaultAttributes; return defaultAttributes;
if (defaultAttributes == nil) { if (defaultAttributes == nil) {
@ -226,7 +226,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (id)parentElement { - (id)parentElement {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) if (!iface || !iface->isValid())
return nil; return nil;
if (QWindow *window = iface->window()) { if (QWindow *window = iface->window()) {
@ -259,7 +259,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (id)accessibilityAttributeValue:(NSString *)attribute { - (id)accessibilityAttributeValue:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) { if (!iface || !iface->isValid()) {
qWarning() << "Called attribute on invalid object: " << axid; qWarning() << "Called attribute on invalid object: " << axid;
return nil; return nil;
} }
@ -336,9 +336,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
} else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) { } else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) {
if (QAccessibleTextInterface *text = iface->textInterface()) { if (QAccessibleTextInterface *text = iface->textInterface()) {
int line = -1; int line = 0; // true for all single line edits
int position = text->cursorPosition(); if (iface->state().multiLine) {
convertLineOffset(text, &line, &position); int position = text->cursorPosition();
convertLineOffset(text, &line, &position);
}
return [NSNumber numberWithInt: line]; return [NSNumber numberWithInt: line];
} }
return nil; return nil;
@ -354,7 +356,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (NSArray *)accessibilityParameterizedAttributeNames { - (NSArray *)accessibilityParameterizedAttributeNames {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) { if (!iface || !iface->isValid()) {
qWarning() << "Called attribute on invalid object: " << axid; qWarning() << "Called attribute on invalid object: " << axid;
return nil; return nil;
} }
@ -379,7 +381,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter { - (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) { if (!iface || !iface->isValid()) {
qWarning() << "Called attribute on invalid object: " << axid; qWarning() << "Called attribute on invalid object: " << axid;
return nil; return nil;
} }
@ -446,7 +448,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { - (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) if (!iface || !iface->isValid())
return NO; return NO;
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
@ -465,7 +467,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) if (!iface || !iface->isValid())
return; return;
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
if (QAccessibleActionInterface *action = iface->actionInterface()) if (QAccessibleActionInterface *action = iface->actionInterface())
@ -494,7 +496,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (NSArray *)accessibilityActionNames { - (NSArray *)accessibilityActionNames {
NSMutableArray * nsActions = [NSMutableArray new]; NSMutableArray * nsActions = [NSMutableArray new];
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) if (!iface || !iface->isValid())
return nsActions; return nsActions;
const QStringList &supportedActionNames = QAccessibleBridgeUtils::effectiveActionNames(iface); const QStringList &supportedActionNames = QAccessibleBridgeUtils::effectiveActionNames(iface);
@ -509,7 +511,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
- (NSString *)accessibilityActionDescription:(NSString *)action { - (NSString *)accessibilityActionDescription:(NSString *)action {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) if (!iface || !iface->isValid())
return nil; // FIXME is that the right return type?? return nil; // FIXME is that the right return type??
QString qtAction = QCocoaAccessible::translateAction(action, iface); QString qtAction = QCocoaAccessible::translateAction(action, iface);
QString description; QString description;

View File

@ -126,7 +126,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
if ([mSavePanel respondsToSelector:@selector(setLevel:)]) if ([mSavePanel respondsToSelector:@selector(setLevel:)])
[mSavePanel setLevel:NSModalPanelWindowLevel]; [mSavePanel setLevel:NSModalPanelWindowLevel];
[mSavePanel setDelegate:self];
mReturnCode = -1; mReturnCode = -1;
mHelper = helper; mHelper = helper;
mNameFilterDropDownList = new QStringList(mOptions->nameFilters()); mNameFilterDropDownList = new QStringList(mOptions->nameFilters());
@ -147,7 +147,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
[self createTextField]; [self createTextField];
[self createAccessory]; [self createAccessory];
[mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil]; [mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil];
// -setAccessoryView: can result in -panel:directoryDidChange:
// resetting our mCurrentDir, set the delegate
// here to make sure it gets the correct value.
[mSavePanel setDelegate:self];
if (mOptions->isLabelExplicitlySet(QFileDialogOptions::Accept)) if (mOptions->isLabelExplicitlySet(QFileDialogOptions::Accept))
[mSavePanel setPrompt:[self strip:options->labelText(QFileDialogOptions::Accept)]]; [mSavePanel setPrompt:[self strip:options->labelText(QFileDialogOptions::Accept)]];

View File

@ -188,11 +188,8 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{ {
// If there is a "root" window into which raster and QOpenGLWidget content is
// composited, all other contexts must share with its context.
QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context();
EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display(); EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display();
QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); QPlatformOpenGLContext *share = context->shareHandle();
QVariant nativeHandle = context->nativeHandle(); QVariant nativeHandle = context->nativeHandle();
QEglFSContext *ctx; QEglFSContext *ctx;

View File

@ -138,6 +138,14 @@ void QEglFSWindow::create()
if (!context->create()) if (!context->create())
qFatal("EGLFS: Failed to create compositing context"); qFatal("EGLFS: Failed to create compositing context");
compositor->setTarget(context, window()); compositor->setTarget(context, window());
// If there is a "root" window into which raster and QOpenGLWidget content is
// composited, all other contexts must share with its context.
if (!qt_gl_global_share_context()) {
qt_gl_set_global_share_context(context);
// What we set up here is in effect equivalent to the application setting
// AA_ShareOpenGLContexts. Set the attribute to be fully consistent.
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
}
} }
} }

View File

@ -155,7 +155,7 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
if (QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha) if (QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha)
m_alphaNeedsFill = true; m_alphaNeedsFill = true;
else // upgrade but here we know app painting does not rely on alpha hence no need to fill else // upgrade but here we know app painting does not rely on alpha hence no need to fill
format = qt_alphaVersionForPainting(format); format = qt_maybeAlphaVersionWithSameDepth(format);
QWindowsNativeImage *oldwni = m_image.data(); QWindowsNativeImage *oldwni = m_image.data();
QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format); QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format);

View File

@ -759,12 +759,17 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
transform.m21 = matrix.m21(); transform.m21 = matrix.m21();
transform.m22 = matrix.m22(); transform.m22 = matrix.m22();
DWRITE_RENDERING_MODE renderMode =
fontDef.hintingPreference == QFont::PreferNoHinting
? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC
: DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
IDWriteGlyphRunAnalysis *glyphAnalysis = NULL; IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis( HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
&glyphRun, &glyphRun,
1.0f, 1.0f,
&transform, &transform,
DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, renderMode,
DWRITE_MEASURING_MODE_NATURAL, DWRITE_MEASURING_MODE_NATURAL,
0.0, 0.0, 0.0, 0.0,
&glyphAnalysis &glyphAnalysis

View File

@ -49,6 +49,7 @@
#include <QOffscreenSurface> #include <QOffscreenSurface>
#include <QOpenGLContext> #include <QOpenGLContext>
#include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -148,14 +149,17 @@ bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface)
Q_D(QWinRTEGLContext); Q_D(QWinRTEGLContext);
Q_ASSERT(windowSurface->surface()->supportsOpenGL()); Q_ASSERT(windowSurface->surface()->supportsOpenGL());
if (windowSurface->surface()->surfaceClass() == QSurface::Offscreen) EGLSurface surface;
return false; if (windowSurface->surface()->surfaceClass() == QSurface::Window) {
QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
if (window->eglSurface() == EGL_NO_SURFACE)
window->createEglSurface(g->eglDisplay, d->eglConfig);
QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface); surface = window->eglSurface();
if (window->eglSurface() == EGL_NO_SURFACE) } else { // Offscreen
window->createEglSurface(g->eglDisplay, d->eglConfig); surface = static_cast<QEGLPbuffer *>(windowSurface)->pbuffer();
}
EGLSurface surface = window->eglSurface();
if (surface == EGL_NO_SURFACE) if (surface == EGL_NO_SURFACE)
return false; return false;
@ -346,4 +350,9 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName)
return eglGetProcAddress(procName.constData()); return eglGetProcAddress(procName.constData());
} }
EGLDisplay QWinRTEGLContext::display()
{
return g->eglDisplay;
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -38,6 +38,7 @@
#define QWINDOWSEGLCONTEXT_H #define QWINDOWSEGLCONTEXT_H
#include <qpa/qplatformopenglcontext.h> #include <qpa/qplatformopenglcontext.h>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -57,6 +58,7 @@ public:
QSurfaceFormat format() const Q_DECL_OVERRIDE; QSurfaceFormat format() const Q_DECL_OVERRIDE;
QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE; QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
static EGLDisplay display();
private: private:
QScopedPointer<QWinRTEGLContextPrivate> d_ptr; QScopedPointer<QWinRTEGLContextPrivate> d_ptr;
Q_DECLARE_PRIVATE(QWinRTEGLContext) Q_DECLARE_PRIVATE(QWinRTEGLContext)

View File

@ -45,12 +45,17 @@
#include "qwinrtfontdatabase.h" #include "qwinrtfontdatabase.h"
#include "qwinrttheme.h" #include "qwinrttheme.h"
#include <QtGui/QSurface> #include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLContext>
#include <qfunctions_winrt.h> #include <QtGui/QSurface>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformoffscreensurface.h> #include <qpa/qplatformoffscreensurface.h>
#include <qfunctions_winrt.h>
#include <functional> #include <functional>
#include <wrl.h> #include <wrl.h>
#include <windows.ui.xaml.h> #include <windows.ui.xaml.h>
@ -385,11 +390,20 @@ HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *)
QPlatformOffscreenSurface *QWinRTIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const QPlatformOffscreenSurface *QWinRTIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{ {
// This is only used for shutdown of applications. QEGLPbuffer *pbuffer = nullptr;
// In case we do not return an empty surface the scenegraph will try HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([&pbuffer, surface]() {
// to create a new native window during application exit causing crashes pbuffer = new QEGLPbuffer(QWinRTEGLContext::display(), surface->requestedFormat(), surface);
// or assertions. return S_OK;
return new QPlatformOffscreenSurface(surface); });
if (hr == UI_E_WINDOW_CLOSED) {
// This is only used for shutdown of applications.
// In case we do not return an empty surface the scenegraph will try
// to create a new native window during application exit causing crashes
// or assertions.
return new QPlatformOffscreenSurface(surface);
}
return pbuffer;
} }

View File

@ -133,6 +133,15 @@ QWinRTWindow::QWinRTWindow(QWindow *window)
hr = d->swapChainPanel.As(&d->uiElement); hr = d->swapChainPanel.As(&d->uiElement);
Q_ASSERT_SUCCEEDED(hr); Q_ASSERT_SUCCEEDED(hr);
ComPtr<Xaml::IFrameworkElement> frameworkElement;
hr = d->swapChainPanel.As(&frameworkElement);
Q_ASSERT_SUCCEEDED(hr);
const QSizeF size = QSizeF(d->screen->geometry().size()) / d->screen->scaleFactor();
hr = frameworkElement->put_Width(size.width());
Q_ASSERT_SUCCEEDED(hr);
hr = frameworkElement->put_Height(size.height());
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IDependencyObject> canvas = d->screen->canvas(); ComPtr<IDependencyObject> canvas = d->screen->canvas();
ComPtr<IPanel> panel; ComPtr<IPanel> panel;
hr = canvas.As(&panel); hr = canvas.As(&panel);

View File

@ -179,7 +179,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI
m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha;
if (!m_hasAlpha) if (!m_hasAlpha)
format = qt_alphaVersionForPainting(format); format = qt_maybeAlphaVersionWithSameDepth(format);
m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format); m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
m_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage); m_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage);

View File

@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1); Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1); Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1);
namespace QTest namespace QTest
{ {
@ -93,7 +93,7 @@ namespace QTest
if (action == Shortcut) { if (action == Shortcut) {
int timestamp = 0; int timestamp = 0;
qt_handleShortcutEvent(window, timestamp, code, modifier, text, repeat); qt_sendShortcutOverrideEvent(window, timestamp, code, modifier, text, repeat);
return; return;
} }
@ -174,7 +174,7 @@ namespace QTest
QKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat); QKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat);
QSpontaneKeyEvent::setSpontaneous(&a); QSpontaneKeyEvent::setSpontaneous(&a);
if (press && qt_handleShortcutEvent(widget, a.timestamp(), code, modifier, text, repeat)) if (press && qt_sendShortcutOverrideEvent(widget, a.timestamp(), code, modifier, text, repeat))
return; return;
if (!qApp->notify(widget, &a)) if (!qApp->notify(widget, &a))
QTest::qWarn("Keyboard event not accepted by receiving widget"); QTest::qWarn("Keyboard event not accepted by receiving widget");

View File

@ -1059,6 +1059,31 @@ static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra)
return false; return false;
} }
bool QWidgetBackingStore::syncAllowed()
{
#ifndef QT_NO_OPENGL
QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
if (textureListWatcher && !textureListWatcher->isLocked()) {
textureListWatcher->deleteLater();
textureListWatcher = 0;
} else if (!tlwExtra->widgetTextures.isEmpty()) {
bool skipSync = false;
foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) {
if (tl->isLocked()) {
if (!textureListWatcher)
textureListWatcher = new QPlatformTextureListWatcher(this);
if (!textureListWatcher->isLocked())
textureListWatcher->watch(tl);
skipSync = true;
}
}
if (skipSync) // cannot compose due to widget textures being in use
return false;
}
#endif
return true;
}
/*! /*!
Synchronizes the \a exposedRegion of the \a exposedWidget with the backing store. Synchronizes the \a exposedRegion of the \a exposedWidget with the backing store.
@ -1089,7 +1114,8 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
else else
markDirtyOnScreen(exposedRegion, exposedWidget, QPoint()); markDirtyOnScreen(exposedRegion, exposedWidget, QPoint());
doSync(); if (syncAllowed())
doSync();
} }
/*! /*!
@ -1115,27 +1141,8 @@ void QWidgetBackingStore::sync()
return; return;
} }
#ifndef QT_NO_OPENGL if (syncAllowed())
if (textureListWatcher && !textureListWatcher->isLocked()) { doSync();
textureListWatcher->deleteLater();
textureListWatcher = 0;
} else if (!tlwExtra->widgetTextures.isEmpty()) {
bool skipSync = false;
foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) {
if (tl->isLocked()) {
if (!textureListWatcher)
textureListWatcher = new QPlatformTextureListWatcher(this);
if (!textureListWatcher->isLocked())
textureListWatcher->watch(tl);
skipSync = true;
}
}
if (skipSync) // cannot compose due to widget textures being in use
return;
}
#endif
doSync();
} }
void QWidgetBackingStore::doSync() void QWidgetBackingStore::doSync()

View File

@ -164,6 +164,8 @@ private:
void updateLists(QWidget *widget); void updateLists(QWidget *widget);
bool syncAllowed();
inline void addDirtyWidget(QWidget *widget, const QRegion &rgn) inline void addDirtyWidget(QWidget *widget, const QRegion &rgn)
{ {
if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) { if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) {

View File

@ -708,7 +708,6 @@ void QWidgetWindow::handleCloseEvent(QCloseEvent *event)
{ {
bool is_closing = m_widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); bool is_closing = m_widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
event->setAccepted(is_closing); event->setAccepted(is_closing);
QWindow::event(event); // Call QWindow QCloseEvent handler.
} }
#ifndef QT_NO_WHEELEVENT #ifndef QT_NO_WHEELEVENT

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

View File

@ -1482,6 +1482,7 @@ void tst_QImageReader::readCorruptImage_data()
QTest::newRow("corrupt gif") << QString("corrupt.gif") << true << QString("") << QByteArray("gif"); QTest::newRow("corrupt gif") << QString("corrupt.gif") << true << QString("") << QByteArray("gif");
QTest::newRow("corrupt png") << QString("corrupt.png") << true << QString("") << QByteArray("png"); QTest::newRow("corrupt png") << QString("corrupt.png") << true << QString("") << QByteArray("png");
QTest::newRow("corrupt bmp") << QString("corrupt.bmp") << true << QString("") << QByteArray("bmp"); QTest::newRow("corrupt bmp") << QString("corrupt.bmp") << true << QString("") << QByteArray("bmp");
QTest::newRow("corrupt bmp (clut)") << QString("corrupt_clut.bmp") << true << QString("") << QByteArray("bmp");
QTest::newRow("corrupt xpm (colors)") << QString("corrupt-colors.xpm") << true QTest::newRow("corrupt xpm (colors)") << QString("corrupt-colors.xpm") << true
<< QString("QImage: XPM color specification is missing: bla9an.n#x") << QString("QImage: XPM color specification is missing: bla9an.n#x")
<< QByteArray("xpm"); << QByteArray("xpm");

View File

@ -70,6 +70,7 @@ private slots:
void setRawDataAndGetAsVector(); void setRawDataAndGetAsVector();
void boundingRect(); void boundingRect();
void mixedScripts(); void mixedScripts();
void multiLineBoundingRect();
private: private:
int m_testFontId; int m_testFontId;
@ -735,6 +736,34 @@ void tst_QGlyphRun::mixedScripts()
QCOMPARE(glyphRuns.size(), 2); QCOMPARE(glyphRuns.size(), 2);
} }
void tst_QGlyphRun::multiLineBoundingRect()
{
QTextLayout layout;
layout.setText("Foo Bar");
layout.beginLayout();
QTextLine line = layout.createLine();
line.setNumColumns(4);
line.setPosition(QPointF(0, 0));
line = layout.createLine();
line.setPosition(QPointF(0, 10));
layout.endLayout();
QCOMPARE(layout.lineCount(), 2);
QList<QGlyphRun> firstLineGlyphRuns = layout.lineAt(0).glyphRuns();
QList<QGlyphRun> allGlyphRuns = layout.glyphRuns();
QCOMPARE(firstLineGlyphRuns.size(), 1);
QCOMPARE(allGlyphRuns.size(), 1);
QGlyphRun firstLineGlyphRun = firstLineGlyphRuns.first();
QGlyphRun allGlyphRun = allGlyphRuns.first();
QVERIFY(firstLineGlyphRun.boundingRect().height() < allGlyphRun.boundingRect().height());
}
#endif // QT_NO_RAWFONT #endif // QT_NO_RAWFONT
QTEST_MAIN(tst_QGlyphRun) QTEST_MAIN(tst_QGlyphRun)

View File

@ -181,6 +181,13 @@ int main(int argc, char *argv[])
glw3->setObjectName("GL widget in scroll area (possibly native)"); glw3->setObjectName("GL widget in scroll area (possibly native)");
glw3->setFormat(format); glw3->setFormat(format);
glw3->setFixedSize(600, 600); glw3->setFixedSize(600, 600);
OpenGLWidget *glw3child = new OpenGLWidget(0);
const float glw3ClearColor[] = { 0.5f, 0.2f, 0.8f };
glw3child->setClearColor(glw3ClearColor);
glw3child->setObjectName("Child widget of GL Widget in scroll area");
glw3child->setFormat(format);
glw3child->setParent(glw3);
glw3child->setGeometry(500, 500, 100, 100); // lower right corner of parent
QScrollArea *sa = new QScrollArea; QScrollArea *sa = new QScrollArea;
sa->setWidget(glw3); sa->setWidget(glw3);
sa->setMinimumSize(100, 100); sa->setMinimumSize(100, 100);

View File

@ -78,6 +78,8 @@ public:
int m_interval; int m_interval;
QVector3D m_rotAxis; QVector3D m_rotAxis;
float clearColor[3];
}; };
@ -85,6 +87,7 @@ OpenGLWidget::OpenGLWidget(int interval, const QVector3D &rotAxis, QWidget *pare
: QOpenGLWidget(parent) : QOpenGLWidget(parent)
{ {
d.reset(new OpenGLWidgetPrivate(this)); d.reset(new OpenGLWidgetPrivate(this));
d->clearColor[0] = d->clearColor[1] = d->clearColor[2] = 0.0f;
d->m_interval = interval; d->m_interval = interval;
d->m_rotAxis = rotAxis; d->m_rotAxis = rotAxis;
if (interval > 0) { if (interval > 0) {
@ -151,7 +154,7 @@ void OpenGLWidgetPrivate::render()
const qreal retinaScale = q->devicePixelRatio(); const qreal retinaScale = q->devicePixelRatio();
glViewport(0, 0, width() * retinaScale, height() * retinaScale); glViewport(0, 0, width() * retinaScale, height() * retinaScale);
glClearColor(0.0, 0.0, 0.0, 1.0); glClearColor(clearColor[0], clearColor[1], clearColor[2], 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
m_program->bind(); m_program->bind();
@ -194,3 +197,10 @@ void OpenGLWidgetPrivate::render()
if (m_interval <= 0) if (m_interval <= 0)
q->update(); q->update();
} }
void OpenGLWidget::setClearColor(const float *c)
{
d->clearColor[0] = c[0];
d->clearColor[1] = c[1];
d->clearColor[2] = c[2];
}

View File

@ -49,6 +49,8 @@ public:
void resizeGL(int w, int h); void resizeGL(int w, int h);
void paintGL(); void paintGL();
void setClearColor(const float *c);
private: private:
QScopedPointer<OpenGLWidgetPrivate> d; QScopedPointer<OpenGLWidgetPrivate> d;
}; };