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++
;;
FreeBSD:*)
PLATFORM=freebsd-g++
PLATFORM=freebsd-clang
PLATFORM_NOTES="
- 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
!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
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@
verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < $${verscript}.in > $@
verscriptprocess.target = $$verscript
verscript_in = $${verscript}.in
verscriptprocess.name = linker version script ${QMAKE_FILE_BASE}
verscriptprocess.input = verscript_in
verscriptprocess.CONFIG += no_link target_predeps
for(header, SYNCQT.PRIVATE_HEADER_FILES): \
verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header
verscriptprocess.depends += $${verscript}.in
QMAKE_EXTRA_TARGETS += verscriptprocess
PRE_TARGETDEPS += $$verscript
verscript = $${verscript}.in
verscriptprocess.output = $$verscript
verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < ${QMAKE_FILE_IN} > $@
silent:verscriptprocess.commands = @echo creating linker version script ${QMAKE_FILE_BASE} && $$verscriptprocess.commands
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(previous)
unset(verscript)

View File

@ -49,9 +49,15 @@ for(resource, RESOURCES) {
for(file, $${resource}.files) {
abs_path = $$absolute_path($$file, $$_PRO_FILE_PWD_)
alias = $$relative_path($$abs_path, $$abs_base)
resource_file_content += \
"<file alias=\"$$xml_escape($$alias)\">$$xml_escape($$abs_path)</file>"
files = $$files($$abs_path/*, true)
isEmpty(files): \
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 += \

View File

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

View File

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

View File

@ -59,11 +59,7 @@ QT_BEGIN_NAMESPACE
#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_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"
# else
# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOTPCREL\n"
# endif
# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
# else // x86
# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n"
# endif

View File

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

View File

@ -103,6 +103,7 @@ public:
protected:
QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0);
virtual void sendPostedEvents();
void doUnregisterSocketNotifier(QSocketNotifier *notifier);
private:
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/qatomic.h>
#if QT_DEPRECATED_SINCE(5, 5)
#if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/qhash.h>
#endif
#include <QtCore/qhashfunctions.h>

View File

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

View File

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

View File

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

View File

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

View File

@ -63,6 +63,9 @@
#include "qdbusthreaddebug_p.h"
#include <algorithm>
#ifdef interface
#undef interface
#endif
#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) {
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;
image.setColorCount(ncols);
}

View File

@ -189,6 +189,12 @@ inline QImage::Format qt_alphaVersion(QImage::Format format)
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)
{
QImage::Format toFormat = qt_alphaVersion(format);

View File

@ -47,6 +47,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qmargins.h>
#include <QtCore/qmath.h>
#include <QtCore/qrect.h>
#include <QtCore/qvector.h>
#include <QtCore/qloggingcategory.h>
@ -382,6 +383,24 @@ inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *
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)
{
if (!QHighDpiScaling::isActive())
@ -498,6 +517,8 @@ namespace QHighDpi {
template <typename T> inline
T fromNativeLocalRegion(const T &value, ...) { return value; }
template <typename T> inline
T fromNativeLocalExposedRegion(const T &value, ...) { return value; }
template <typename T> inline
T toNativeLocalRegion(const T &value, ...) { return value; }
template <typename T> inline

View File

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

View File

@ -582,7 +582,8 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
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);
}
@ -868,7 +869,7 @@ Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::Keybo
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

View File

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

View File

@ -106,7 +106,8 @@ void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &off
}
#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,
QOpenGLTextureBlitter *blitter, const QPoint &offset)
{
const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
return;
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
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 srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
@ -514,7 +516,23 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
if (needsConversion)
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();
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 (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 rect = dirtyRegion.boundingRect() & imageRect;
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
if (hasUnpackRowLength) {
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
image.constScanLine(rect.y()) + rect.x() * 4);
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
image.constScanLine(rect.y()) + rect.x() * bytesPerPixel);
} else {
// if the rect is wide enough it's cheaper to just
// 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;
}
#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);
if (os2 && os2->sxHeight) {
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();
return answer;
}
@ -1267,7 +1267,7 @@ QFixed QFontEngineFT::averageCharWidth() const
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
if (os2 && os2->xAvgCharWidth) {
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();
return answer;
}
@ -1295,7 +1295,7 @@ void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) c
kerning_pairs_loaded = true;
lockFace();
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();
const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor);
} else {

View File

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

View File

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

View File

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

View File

@ -1704,7 +1704,7 @@ bool QTextDocumentPrivate::ensureMaximumBlockCount()
beginEditBlock();
const int blocksToRemove = blocks.numNodes() - maximumBlockCount;
QTextCursor cursor(*this, 0);
QTextCursor cursor(this, 0);
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, blocksToRemove);
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<QPointF> positions = oldGlyphRun.positions();
QRectF boundingRect = oldGlyphRun.boundingRect();
indexes += glyphRun.glyphIndexes();
positions += glyphRun.positions();
boundingRect = boundingRect.united(glyphRun.boundingRect());
oldGlyphRun.setGlyphIndexes(indexes);
oldGlyphRun.setPositions(positions);
oldGlyphRun.setBoundingRect(boundingRect);
} else {
glyphRunHash[key] = glyphRun;
}

View File

@ -37,7 +37,7 @@
#include <QtCore/QtGlobal>
#include <QtCore/QString>
#include <QtCore/QMetaType>
#if QT_DEPRECATED_SINCE(5, 5)
#if QT_DEPRECATED_SINCE(5, 6)
#include <QtCore/QHash>
#endif
#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
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,
raised and lowered (addWindow(), moveToTop(), etc.), and to
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)
{
const QRect rectInWindow = textures->geometry(idx);
QRect clipRect = textures->clipRect(idx);
const QRect clipRect = textures->clipRect(idx);
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 srcRect = toBottomLeftRect(clipRect, rectInWindow.height());

View File

@ -34,6 +34,7 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QWindow>
#include <QtGui/QPainter>
#include <QtGui/QOffscreenSurface>
#include <qpa/qplatformbackingstore.h>
#include <private/qwindow_p.h>
@ -82,13 +83,28 @@ QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore()
{
if (m_bsTexture) {
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())
glDeleteTextures(1, &m_bsTexture);
else
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()
@ -158,16 +174,15 @@ void QOpenGLCompositorBackingStore::updateTexture()
void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
// Called for ordinary raster windows. This is rare since RasterGLSurface
// 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.
// Called for ordinary raster windows.
Q_UNUSED(region);
Q_UNUSED(offset);
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
QOpenGLContext *dstCtx = compositor->context();
Q_ASSERT(dstCtx);
QWindow *dstWin = compositor->targetWindow();
if (!dstWin)
return;
@ -184,7 +199,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi
QPlatformTextureList *textures, QOpenGLContext *context,
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(offset);
@ -193,6 +208,12 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
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();
if (!dstWin)
return;
@ -254,6 +275,7 @@ void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &sta
if (m_bsTexture) {
glDeleteTextures(1, &m_bsTexture);
m_bsTexture = 0;
m_bsTextureContext = Q_NULLPTR;
}
}

View File

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

View File

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

View File

@ -126,7 +126,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
if ([mSavePanel respondsToSelector:@selector(setLevel:)])
[mSavePanel setLevel:NSModalPanelWindowLevel];
[mSavePanel setDelegate:self];
mReturnCode = -1;
mHelper = helper;
mNameFilterDropDownList = new QStringList(mOptions->nameFilters());
@ -147,7 +147,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
[self createTextField];
[self createAccessory];
[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))
[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
{
// 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();
QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle();
QPlatformOpenGLContext *share = context->shareHandle();
QVariant nativeHandle = context->nativeHandle();
QEglFSContext *ctx;

View File

@ -138,6 +138,14 @@ void QEglFSWindow::create()
if (!context->create())
qFatal("EGLFS: Failed to create compositing context");
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)
m_alphaNeedsFill = true;
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 *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.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;
HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
&glyphRun,
1.0f,
&transform,
DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
renderMode,
DWRITE_MEASURING_MODE_NATURAL,
0.0, 0.0,
&glyphAnalysis

View File

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

View File

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

View File

@ -45,12 +45,17 @@
#include "qwinrtfontdatabase.h"
#include "qwinrttheme.h"
#include <QtGui/QSurface>
#include <QtGui/QOffscreenSurface>
#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 <qfunctions_winrt.h>
#include <functional>
#include <wrl.h>
#include <windows.ui.xaml.h>
@ -385,11 +390,20 @@ HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *)
QPlatformOffscreenSurface *QWinRTIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
// 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);
QEGLPbuffer *pbuffer = nullptr;
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([&pbuffer, surface]() {
pbuffer = new QEGLPbuffer(QWinRTEGLContext::display(), surface->requestedFormat(), surface);
return S_OK;
});
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);
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<IPanel> 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;
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_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage);

View File

@ -57,7 +57,7 @@
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 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
{
@ -93,7 +93,7 @@ namespace QTest
if (action == Shortcut) {
int timestamp = 0;
qt_handleShortcutEvent(window, timestamp, code, modifier, text, repeat);
qt_sendShortcutOverrideEvent(window, timestamp, code, modifier, text, repeat);
return;
}
@ -174,7 +174,7 @@ namespace QTest
QKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat);
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;
if (!qApp->notify(widget, &a))
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;
}
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.
@ -1089,7 +1114,8 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
else
markDirtyOnScreen(exposedRegion, exposedWidget, QPoint());
doSync();
if (syncAllowed())
doSync();
}
/*!
@ -1115,27 +1141,8 @@ void QWidgetBackingStore::sync()
return;
}
#ifndef QT_NO_OPENGL
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;
}
#endif
doSync();
if (syncAllowed())
doSync();
}
void QWidgetBackingStore::doSync()

View File

@ -164,6 +164,8 @@ private:
void updateLists(QWidget *widget);
bool syncAllowed();
inline void addDirtyWidget(QWidget *widget, const QRegion &rgn)
{
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);
event->setAccepted(is_closing);
QWindow::event(event); // Call QWindow QCloseEvent handler.
}
#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 png") << QString("corrupt.png") << true << QString("") << QByteArray("png");
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
<< QString("QImage: XPM color specification is missing: bla9an.n#x")
<< QByteArray("xpm");

View File

@ -70,6 +70,7 @@ private slots:
void setRawDataAndGetAsVector();
void boundingRect();
void mixedScripts();
void multiLineBoundingRect();
private:
int m_testFontId;
@ -735,6 +736,34 @@ void tst_QGlyphRun::mixedScripts()
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
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->setFormat(format);
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;
sa->setWidget(glw3);
sa->setMinimumSize(100, 100);

View File

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