Merge "Merge remote-tracking branch 'origin/5.12' into 5.13"

This commit is contained in:
Liang Qi 2019-08-12 13:23:11 +02:00
commit 41f77a6179
33 changed files with 369 additions and 184 deletions

View File

@ -1 +1,2 @@
SOURCES = arch.cpp SOURCES = arch.cpp
include(write_info.pri)

View File

@ -1,2 +1,3 @@
option(host_build) option(host_build)
SOURCES = arch.cpp SOURCES = arch.cpp
include(write_info.pri)

View File

@ -0,0 +1,17 @@
targetinfofile = $$basename(_PRO_FILE_)
targetinfofile ~= s/pro$/target.txt/
win32 {
ext = .exe
} else:android {
file_prefix = lib
ext = .so
} else:wasm {
equals(WASM_OBJECT_FILES, 1): \
ext = .o
else: \
ext = .wasm
}
content = $${file_prefix}$${TARGET}$${ext}
write_file($$OUT_PWD/$$targetinfofile, content)

View File

@ -286,37 +286,13 @@ defineTest(qtConfTest_architecture) {
!qtConfTest_compile($${1}): \ !qtConfTest_compile($${1}): \
error("Could not determine $$eval($${1}.label). See config.log for details.") error("Could not determine $$eval($${1}.label). See config.log for details.")
host = $$eval($${1}.host)
isEmpty(host): host = false
file_prefix =
exts = -
$$host {
equals(QMAKE_HOST.os, Windows): \
exts = .exe
} else {
win32 {
exts = .exe
} else:android {
file_prefix = lib
exts = .so
} else:wasm {
exts = .wasm .o
}
}
test = $$eval($${1}.test) test = $$eval($${1}.test)
output = $$eval($${1}.output) output = $$eval($${1}.output)
test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)/$$test test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)/$$test
test_out_file = test_out_file = $$test_out_dir/$$cat($$test_out_dir/$${output}.target.txt)
for(ext, exts) { exists($$test_out_file): \
equals(ext, -): ext = content = $$cat($$test_out_file, blob)
f = $$test_out_dir/$$file_prefix$$output$$ext else: \
exists($$f) {
test_out_file = $$f
break()
}
}
isEmpty(test_out_file): \
error("$$eval($${1}.label) detection binary not found.") error("$$eval($${1}.label) detection binary not found.")
content = $$cat($$test_out_file, blob) content = $$cat($$test_out_file, blob)

View File

@ -1,5 +1,9 @@
load(default_post) load(default_post)
# Recompute SDK version in case the user set it explicitly
sdk_version = $$QMAKE_MAC_SDK_VERSION
QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion)
contains(TEMPLATE, .*app) { contains(TEMPLATE, .*app) {
!macx-xcode:if(isEmpty(BUILDS)|build_pass) { !macx-xcode:if(isEmpty(BUILDS)|build_pass) {
# Detect changes to the platform SDK # Detect changes to the platform SDK
@ -14,7 +18,7 @@ contains(TEMPLATE, .*app) {
!versionAtLeast(QMAKE_MAC_SDK_VERSION, $$QT_MAC_SDK_VERSION_MIN): \ !versionAtLeast(QMAKE_MAC_SDK_VERSION, $$QT_MAC_SDK_VERSION_MIN): \
warning("Qt requires at least version $$QT_MAC_SDK_VERSION_MIN of the platform SDK," \ warning("Qt requires at least version $$QT_MAC_SDK_VERSION_MIN of the platform SDK," \
"you're using $${QMAKE_MAC_SDK_VERSION}. Please upgrade.") "you're building against version $${QMAKE_MAC_SDK_VERSION}. Please upgrade.")
!isEmpty(QT_MAC_SDK_VERSION_MAX) { !isEmpty(QT_MAC_SDK_VERSION_MAX) {
# For Qt developers only # For Qt developers only
@ -244,6 +248,11 @@ macx-xcode {
QMAKE_PCH_OUTPUT_EXT = _${QMAKE_PCH_ARCH}$${QMAKE_PCH_OUTPUT_EXT} QMAKE_PCH_OUTPUT_EXT = _${QMAKE_PCH_ARCH}$${QMAKE_PCH_OUTPUT_EXT}
} }
!equals(sdk_version, $$QMAKE_MAC_SDK_VERSION) {
# Explicit SDK version has been set, respect that
QMAKE_LFLAGS += -Wl,-sdk_version -Wl,$$sdk_version
}
cache(QMAKE_XCODE_DEVELOPER_PATH, stash) cache(QMAKE_XCODE_DEVELOPER_PATH, stash)
!isEmpty(QMAKE_XCODE_VERSION): \ !isEmpty(QMAKE_XCODE_VERSION): \
cache(QMAKE_XCODE_VERSION, stash) cache(QMAKE_XCODE_VERSION, stash)

View File

@ -2583,10 +2583,8 @@
\section1 RC_FILE \section1 RC_FILE
Specifies the name of the resource file for the application. Windows only. Specifies the name of the Windows resource file (.rc) for the
The value of this variable is typically handled by target. See \l{Adding Windows Resource Files}.
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely
needs to be modified.
\target RC_CODEPAGE \target RC_CODEPAGE
\section1 RC_CODEPAGE \section1 RC_CODEPAGE
@ -2649,7 +2647,9 @@
\section1 RES_FILE \section1 RES_FILE
Specifies the name of the compiled Windows resource file for the target. Windows only. Specifies the name of the Windows resource compiler's output
file for this target. See \l{RC_FILE} and \l{Adding Windows Resource Files}.
The value of this variable is typically handled by The value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely qmake or \l{#QMAKESPEC}{qmake.conf} and rarely
needs to be modified. needs to be modified.

View File

@ -174,9 +174,9 @@ class Q_CORE_EXPORT QJsonValueRef
{ {
public: public:
QJsonValueRef(QJsonArray *array, int idx) QJsonValueRef(QJsonArray *array, int idx)
: a(array), is_object(false), index(idx) {} : a(array), is_object(false), index(static_cast<uint>(idx)) {}
QJsonValueRef(QJsonObject *object, int idx) QJsonValueRef(QJsonObject *object, int idx)
: o(object), is_object(true), index(idx) {} : o(object), is_object(true), index(static_cast<uint>(idx)) {}
inline operator QJsonValue() const { return toValue(); } inline operator QJsonValue() const { return toValue(); }
QJsonValueRef &operator = (const QJsonValue &val); QJsonValueRef &operator = (const QJsonValue &val);

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation. ** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the QtCore module of the Qt Toolkit. ** This file is part of the QtCore module of the Qt Toolkit.
@ -132,12 +132,12 @@ QT_BEGIN_NAMESPACE
* We overallocate the byte array by 1 byte. The first user bit is at * We overallocate the byte array by 1 byte. The first user bit is at
* d.data()[1]. On the extra first byte, we store the difference between the * d.data()[1]. On the extra first byte, we store the difference between the
* number of bits in the byte array (including this byte) and the number of * number of bits in the byte array (including this byte) and the number of
* bits in the bit array. Therefore, it's always a number between 8 and 15. * bits in the bit array. Therefore, for a non-empty QBitArray, it's always a
* number between 8 and 15. For the empty one, d is the an empty QByteArray and
* *d.constData() is the QByteArray's terminating NUL (0) byte.
* *
* This allows for fast calculation of the bit array size: * This allows for fast calculation of the bit array size:
* inline int size() const { return (d.size() << 3) - *d.constData(); } * inline int size() const { return (d.size() << 3) - *d.constData(); }
*
* Note: for an array of zero size, *d.constData() is the QByteArray implicit NUL.
*/ */
/*! /*!
@ -326,6 +326,8 @@ void QBitArray::fill(bool value, int begin, int end)
QBitArray QBitArray::fromBits(const char *data, qsizetype size) QBitArray QBitArray::fromBits(const char *data, qsizetype size)
{ {
QBitArray result; QBitArray result;
if (size == 0)
return result;
qsizetype nbytes = (size + 7) / 8; qsizetype nbytes = (size + 7) / 8;
result.d = QByteArray(nbytes + 1, Qt::Uninitialized); result.d = QByteArray(nbytes + 1, Qt::Uninitialized);
@ -334,7 +336,7 @@ QBitArray QBitArray::fromBits(const char *data, qsizetype size)
// clear any unused bits from the last byte // clear any unused bits from the last byte
if (size & 7) if (size & 7)
bits[nbytes] &= 0xffU >> (size & 7); bits[nbytes] &= 0xffU >> (8 - (size & 7));
*bits = result.d.size() * 8 - size; *bits = result.d.size() * 8 - size;
return result; return result;

View File

@ -387,19 +387,19 @@ void QCryptographicHash::addData(const char *data, int length)
break; break;
case RealSha3_224: case RealSha3_224:
case Keccak_224: case Keccak_224:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break; break;
case RealSha3_256: case RealSha3_256:
case Keccak_256: case Keccak_256:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break; break;
case RealSha3_384: case RealSha3_384:
case Keccak_384: case Keccak_384:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break; break;
case RealSha3_512: case RealSha3_512:
case Keccak_512: case Keccak_512:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), quint64(length) * 8);
break; break;
#endif #endif
} }

View File

@ -456,6 +456,8 @@ QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QPlatformS
{ {
if (!m_active) if (!m_active)
return { qreal(1), QPoint() }; return { qreal(1), QPoint() };
if (!platformScreen)
return { m_factor, QPoint() }; // the global factor
const QPlatformScreen *actualScreen = nativePosition ? const QPlatformScreen *actualScreen = nativePosition ?
platformScreen->screenForPosition(*nativePosition) : platformScreen; platformScreen->screenForPosition(*nativePosition) : platformScreen;
return { m_factor * screenSubfactor(actualScreen), actualScreen->geometry().topLeft() }; return { m_factor * screenSubfactor(actualScreen), actualScreen->geometry().topLeft() };

View File

@ -2908,19 +2908,34 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
for (int i = 0; i < numGlyphs; i++) { for (int i = 0; i < numGlyphs; i++) {
QFixed spp = fontEngine->subPixelPositionForX(positions[i].x); QFixed spp = fontEngine->subPixelPositionForX(positions[i].x);
QPoint offset; const QFontEngine::Glyph *alphaMap = fontEngine->glyphData(glyphs[i], spp, neededFormat, s->matrix);
const QImage *alphaMap = fontEngine->lockedAlphaMapForGlyph(glyphs[i], spp, neededFormat, s->matrix, if (!alphaMap)
&offset);
if (alphaMap == 0 || alphaMap->isNull())
continue; continue;
alphaPenBlt(alphaMap->constBits(), alphaMap->bytesPerLine(), alphaMap->depth(), int depth;
qFloor(positions[i].x) + offset.x(), int bytesPerLine;
qRound(positions[i].y) + offset.y(), switch (alphaMap->format) {
alphaMap->width(), alphaMap->height(), case QFontEngine::Format_Mono:
fontEngine->expectsGammaCorrectedBlending()); depth = 1;
bytesPerLine = ((alphaMap->width + 31) & ~31) >> 3;
break;
case QFontEngine::Format_A8:
depth = 8;
bytesPerLine = (alphaMap->width + 3) & ~3;
break;
case QFontEngine::Format_A32:
depth = 32;
bytesPerLine = alphaMap->width * 4;
break;
default:
Q_UNREACHABLE();
};
fontEngine->unlockAlphaMapForGlyph(); alphaPenBlt(alphaMap->data, bytesPerLine, depth,
qFloor(positions[i].x) + alphaMap->x,
qRound(positions[i].y) - alphaMap->y,
alphaMap->width, alphaMap->height,
fontEngine->expectsGammaCorrectedBlending());
} }
} else { } else {

View File

@ -0,0 +1,26 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
Neither the name of Adobe Systems Incorporated nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -923,29 +923,10 @@ QFixed QFontEngine::subPixelPositionForX(QFixed x) const
return subPixelPosition; return subPixelPosition;
} }
QImage *QFontEngine::lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, QFontEngine::Glyph *QFontEngine::glyphData(glyph_t, QFixed,
QFontEngine::GlyphFormat neededFormat, QFontEngine::GlyphFormat, const QTransform &)
const QTransform &t, QPoint *offset)
{ {
Q_ASSERT(currentlyLockedAlphaMap.isNull()); return nullptr;
if (neededFormat == Format_None)
neededFormat = Format_A32;
if (neededFormat != Format_A32)
currentlyLockedAlphaMap = alphaMapForGlyph(glyph, subPixelPosition, t);
else
currentlyLockedAlphaMap = alphaRGBMapForGlyph(glyph, subPixelPosition, t);
if (offset != 0)
*offset = QPoint(0, 0);
return &currentlyLockedAlphaMap;
}
void QFontEngine::unlockAlphaMapForGlyph()
{
Q_ASSERT(!currentlyLockedAlphaMap.isNull());
currentlyLockedAlphaMap = QImage();
} }
QImage QFontEngine::alphaMapForGlyph(glyph_t glyph) QImage QFontEngine::alphaMapForGlyph(glyph_t glyph)

View File

@ -124,6 +124,22 @@ public:
}; };
Q_DECLARE_FLAGS(ShaperFlags, ShaperFlag) Q_DECLARE_FLAGS(ShaperFlags, ShaperFlag)
/* Used with the Freetype font engine. We don't cache glyphs that are too large anyway, so we can make this struct rather small */
struct Glyph {
Glyph() = default;
~Glyph() { delete [] data; }
short linearAdvance = 0;
unsigned char width = 0;
unsigned char height = 0;
short x = 0;
short y = 0;
short advance = 0;
signed char format = 0;
uchar *data = nullptr;
private:
Q_DISABLE_COPY(Glyph);
};
virtual ~QFontEngine(); virtual ~QFontEngine();
inline Type type() const { return m_type; } inline Type type() const { return m_type; }
@ -191,11 +207,7 @@ public:
virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color = QColor()); virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color = QColor());
virtual QImage *lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, virtual Glyph *glyphData(glyph_t glyph, QFixed subPixelPosition, GlyphFormat neededFormat, const QTransform &t);
GlyphFormat neededFormat,
const QTransform &t = QTransform(),
QPoint *offset = 0);
virtual void unlockAlphaMapForGlyph();
virtual bool hasInternalCaching() const { return false; } virtual bool hasInternalCaching() const { return false; }
virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/) virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/)
@ -346,7 +358,6 @@ public:
void loadKerningPairs(QFixed scalingFactor); void loadKerningPairs(QFixed scalingFactor);
GlyphFormat glyphFormat; GlyphFormat glyphFormat;
QImage currentlyLockedAlphaMap;
int m_subPixelPositionCount; // Number of positions within a single pixel for this cache int m_subPixelPositionCount; // Number of positions within a single pixel for this cache
inline QVariant userData() const { return m_userData; } inline QVariant userData() const { return m_userData; }

View File

@ -0,0 +1,17 @@
[
{
"Id": "aglfn",
"Name": "Adobe Glyph List For New Fonts",
"QDocModule": "qtgui",
"Description": "Provides standardized names for glyphs.",
"QtUsage": "Used by PDF generator to make it easier for reader applications to resolve the original contents of rendered text.",
"Path": "qfontsubset_agl.cpp",
"Homepage": "https://github.com/adobe-type-tools/agl-aglfn",
"Version": "1.7",
"License": "BSD 3-Clause \"New\" or \"Revised\" License",
"LicenseId": "BSD-3-Clause",
"LicenseFile": "AGLFN_LICENSE.txt",
"Copyright": "Copyright 2002, 2003, 2005, 2006, 2008, 2010, 2015 Adobe Systems"
}
]

View File

@ -1103,12 +1103,11 @@ void QTextDocumentPrivate::clearUndoRedoStacks(QTextDocument::Stacks stacksToCle
bool redoCommandsAvailable = undoState != undoStack.size(); bool redoCommandsAvailable = undoState != undoStack.size();
if (stacksToClear == QTextDocument::UndoStack && undoCommandsAvailable) { if (stacksToClear == QTextDocument::UndoStack && undoCommandsAvailable) {
for (int i = 0; i < undoState; ++i) { for (int i = 0; i < undoState; ++i) {
QTextUndoCommand c = undoStack.at(undoState); QTextUndoCommand c = undoStack.at(i);
if (c.command & QTextUndoCommand::Custom) if (c.command & QTextUndoCommand::Custom)
delete c.custom; delete c.custom;
} }
undoStack.remove(0, undoState); undoStack.remove(0, undoState);
undoStack.resize(undoStack.size() - undoState);
undoState = 0; undoState = 0;
if (emitSignals) if (emitSignals)
emitUndoAvailable(false); emitUndoAvailable(false);

View File

@ -106,7 +106,7 @@ static bool ft_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *leng
return result; return result;
} }
static QFontEngineFT::Glyph emptyGlyph = {0, 0, 0, 0, 0, 0, 0, 0}; static QFontEngineFT::Glyph emptyGlyph;
static const QFontEngine::HintStyle ftInitialDefaultHintStyle = static const QFontEngine::HintStyle ftInitialDefaultHintStyle =
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@ -556,11 +556,6 @@ void QFreetypeFace::addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point,
slot->bitmap.buffer, slot->bitmap.pitch, slot->bitmap.width, slot->bitmap.rows, path); slot->bitmap.buffer, slot->bitmap.pitch, slot->bitmap.width, slot->bitmap.rows, path);
} }
QFontEngineFT::Glyph::~Glyph()
{
delete [] data;
}
struct LcdFilterDummy struct LcdFilterDummy
{ {
static inline void filterPixel(uchar &, uchar &, uchar &) static inline void filterPixel(uchar &, uchar &, uchar &)
@ -1986,11 +1981,10 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng
return img; return img;
} }
QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixelPosition, QFontEngine::Glyph *QFontEngineFT::glyphData(glyph_t glyphIndex, QFixed subPixelPosition,
QFontEngine::GlyphFormat neededFormat, QFontEngine::GlyphFormat neededFormat, const QTransform &t)
const QTransform &t, QPoint *offset)
{ {
Q_ASSERT(currentlyLockedAlphaMap.isNull()); Q_ASSERT(cacheEnabled);
if (isBitmapFont()) if (isBitmapFont())
neededFormat = Format_Mono; neededFormat = Format_Mono;
@ -2000,33 +1994,10 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe
neededFormat = Format_A8; neededFormat = Format_A8;
Glyph *glyph = loadGlyphFor(glyphIndex, subPixelPosition, neededFormat, t); Glyph *glyph = loadGlyphFor(glyphIndex, subPixelPosition, neededFormat, t);
if (!glyph || !glyph->width || !glyph->height)
if (offset != 0 && glyph != 0)
*offset = QPoint(glyph->x, -glyph->y);
currentlyLockedAlphaMap = alphaMapFromGlyphData(glyph, neededFormat);
const bool glyphHasGeometry = glyph != nullptr && glyph->height != 0 && glyph->width != 0;
if (!cacheEnabled && glyph != &emptyGlyph) {
currentlyLockedAlphaMap = currentlyLockedAlphaMap.copy();
delete glyph;
}
if (!glyphHasGeometry)
return nullptr; return nullptr;
if (currentlyLockedAlphaMap.isNull()) return glyph;
return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset);
QImageData *data = currentlyLockedAlphaMap.data_ptr();
data->is_locked = true;
return &currentlyLockedAlphaMap;
}
void QFontEngineFT::unlockAlphaMapForGlyph()
{
QFontEngine::unlockAlphaMapForGlyph();
} }
static inline bool is2dRotation(const QTransform &t) static inline bool is2dRotation(const QTransform &t)

View File

@ -129,20 +129,6 @@ private:
class QFontEngineFT : public QFontEngine class QFontEngineFT : public QFontEngine
{ {
public: public:
/* we don't cache glyphs that are too large anyway, so we can make this struct rather small */
struct Glyph {
~Glyph();
int linearAdvance : 22;
unsigned char width;
unsigned char height;
short x;
short y;
short advance;
signed char format;
uchar *data;
};
struct GlyphInfo { struct GlyphInfo {
int linearAdvance; int linearAdvance;
unsigned short width; unsigned short width;
@ -241,11 +227,9 @@ private:
QFixed subPixelPosition, QFixed subPixelPosition,
const QTransform &matrix, const QTransform &matrix,
QFontEngine::GlyphFormat format) override; QFontEngine::GlyphFormat format) override;
QImage *lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, Glyph *glyphData(glyph_t glyph, QFixed subPixelPosition,
GlyphFormat neededFormat, const QTransform &t, GlyphFormat neededFormat, const QTransform &t) override;
QPoint *offset) override;
bool hasInternalCaching() const override { return cacheEnabled; } bool hasInternalCaching() const override { return cacheEnabled; }
void unlockAlphaMapForGlyph() override;
bool expectsGammaCorrectedBlending() const override; bool expectsGammaCorrectedBlending() const override;
void removeGlyphFromCache(glyph_t glyph) override; void removeGlyphFromCache(glyph_t glyph) override;

View File

@ -225,10 +225,11 @@ namespace QtAndroidMenu
QString itemText = removeAmpersandEscapes(item->text()); QString itemText = removeAmpersandEscapes(item->text());
jstring jtext = env->NewString(reinterpret_cast<const jchar *>(itemText.data()), jstring jtext = env->NewString(reinterpret_cast<const jchar *>(itemText.data()),
itemText.length()); itemText.length());
jint menuId = platformMenu->menuId(item);
jobject menuItem = env->CallObjectMethod(menu, jobject menuItem = env->CallObjectMethod(menu,
addMenuItemMethodID, addMenuItemMethodID,
menuNoneValue, menuNoneValue,
int(item->tag()), menuId,
order++, order++,
jtext); jtext);
env->DeleteLocalRef(jtext); env->DeleteLocalRef(jtext);
@ -262,10 +263,11 @@ namespace QtAndroidMenu
QString itemText = removeAmpersandEscapes(item->text()); QString itemText = removeAmpersandEscapes(item->text());
jstring jtext = env->NewString(reinterpret_cast<const jchar *>(itemText.data()), jstring jtext = env->NewString(reinterpret_cast<const jchar *>(itemText.data()),
itemText.length()); itemText.length());
jint menuId = visibleMenuBar->menuId(item);
jobject menuItem = env->CallObjectMethod(menu, jobject menuItem = env->CallObjectMethod(menu,
addMenuItemMethodID, addMenuItemMethodID,
menuNoneValue, menuNoneValue,
int(item->tag()), menuId,
order++, order++,
jtext); jtext);
env->DeleteLocalRef(jtext); env->DeleteLocalRef(jtext);
@ -290,7 +292,7 @@ namespace QtAndroidMenu
const QAndroidPlatformMenuBar::PlatformMenusType &menus = visibleMenuBar->menus(); const QAndroidPlatformMenuBar::PlatformMenusType &menus = visibleMenuBar->menus();
if (menus.size() == 1) { // Expanded menu if (menus.size() == 1) { // Expanded menu
QAndroidPlatformMenuItem *item = static_cast<QAndroidPlatformMenuItem *>(menus.front()->menuItemForTag(menuId)); QAndroidPlatformMenuItem *item = static_cast<QAndroidPlatformMenuItem *>(menus.front()->menuItemForId(menuId));
if (item) { if (item) {
if (item->menu()) { if (item->menu()) {
showContextMenu(item->menu(), QRect(), env); showContextMenu(item->menu(), QRect(), env);
@ -301,7 +303,7 @@ namespace QtAndroidMenu
} }
} }
} else { } else {
QAndroidPlatformMenu *menu = static_cast<QAndroidPlatformMenu *>(visibleMenuBar->menuForTag(menuId)); QAndroidPlatformMenu *menu = static_cast<QAndroidPlatformMenu *>(visibleMenuBar->menuForId(menuId));
if (menu) if (menu)
showContextMenu(menu, QRect(), env); showContextMenu(menu, QRect(), env);
} }
@ -341,7 +343,7 @@ namespace QtAndroidMenu
static jboolean onContextItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked) static jboolean onContextItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked)
{ {
QMutexLocker lock(&visibleMenuMutex); QMutexLocker lock(&visibleMenuMutex);
QAndroidPlatformMenuItem * item = static_cast<QAndroidPlatformMenuItem *>(visibleMenu->menuItemForTag(menuId)); QAndroidPlatformMenuItem * item = static_cast<QAndroidPlatformMenuItem *>(visibleMenu->menuItemForId(menuId));
if (item) { if (item) {
if (item->menu()) { if (item->menu()) {
showContextMenu(item->menu(), QRect(), env); showContextMenu(item->menu(), QRect(), env);

View File

@ -62,6 +62,7 @@ void QAndroidPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatform
m_menuItems.end(), m_menuItems.end(),
static_cast<QAndroidPlatformMenuItem *>(before)), static_cast<QAndroidPlatformMenuItem *>(before)),
static_cast<QAndroidPlatformMenuItem *>(menuItem)); static_cast<QAndroidPlatformMenuItem *>(menuItem));
m_menuHash.insert(m_nextMenuId++, menuItem);
} }
void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
@ -72,6 +73,21 @@ void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
static_cast<QAndroidPlatformMenuItem *>(menuItem)); static_cast<QAndroidPlatformMenuItem *>(menuItem));
if (it != m_menuItems.end()) if (it != m_menuItems.end())
m_menuItems.erase(it); m_menuItems.erase(it);
{
int maxId = -1;
QHash<int, QPlatformMenuItem *>::iterator it = m_menuHash.begin();
while (it != m_menuHash.end()) {
if (it.value() == menuItem) {
it = m_menuHash.erase(it);
} else {
maxId = qMax(maxId, it.key());
++it;
}
}
m_nextMenuId = maxId + 1;
}
} }
void QAndroidPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem) void QAndroidPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem)
@ -139,6 +155,16 @@ void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &t
QtAndroidMenu::showContextMenu(this, targetRect, QJNIEnvironmentPrivate()); QtAndroidMenu::showContextMenu(this, targetRect, QJNIEnvironmentPrivate());
} }
QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const
{
for (QAndroidPlatformMenuItem *menuItem : m_menuItems) {
if (menuItem->tag() == tag)
return menuItem;
}
return nullptr;
}
QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const
{ {
if (position < m_menuItems.size()) if (position < m_menuItems.size())
@ -146,13 +172,20 @@ QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const
return 0; return 0;
} }
QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const int QAndroidPlatformMenu::menuId(QPlatformMenuItem *menu) const
{ {
for (QPlatformMenuItem *menuItem : m_menuItems) { QHash<int, QPlatformMenuItem *>::const_iterator it;
if (menuItem->tag() == tag) for (it = m_menuHash.constBegin(); it != m_menuHash.constEnd(); ++it) {
return menuItem; if (it.value() == menu)
return it.key();
} }
return 0;
return -1;
}
QPlatformMenuItem *QAndroidPlatformMenu::menuItemForId(int menuId) const
{
return m_menuHash.value(menuId);
} }
QAndroidPlatformMenu::PlatformMenuItemsType QAndroidPlatformMenu::menuItems() const QAndroidPlatformMenu::PlatformMenuItemsType QAndroidPlatformMenu::menuItems() const

View File

@ -73,6 +73,8 @@ public:
QPlatformMenuItem *menuItemAt(int position) const override; QPlatformMenuItem *menuItemAt(int position) const override;
QPlatformMenuItem *menuItemForTag(quintptr tag) const override; QPlatformMenuItem *menuItemForTag(quintptr tag) const override;
QPlatformMenuItem *menuItemForId(int menuId) const;
int menuId(QPlatformMenuItem *menuItem) const;
PlatformMenuItemsType menuItems() const; PlatformMenuItemsType menuItems() const;
QMutex *menuItemsMutex(); QMutex *menuItemsMutex();
@ -84,6 +86,9 @@ private:
bool m_enabled; bool m_enabled;
bool m_isVisible; bool m_isVisible;
QMutex m_menuItemsMutex; QMutex m_menuItemsMutex;
int m_nextMenuId = 0;
QHash<int, QPlatformMenuItem *> m_menuHash;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -61,6 +61,7 @@ void QAndroidPlatformMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *bef
m_menus.end(), m_menus.end(),
static_cast<QAndroidPlatformMenu *>(before)), static_cast<QAndroidPlatformMenu *>(before)),
static_cast<QAndroidPlatformMenu *>(menu)); static_cast<QAndroidPlatformMenu *>(menu));
m_menuHash.insert(m_nextMenuId++, menu);
} }
void QAndroidPlatformMenuBar::removeMenu(QPlatformMenu *menu) void QAndroidPlatformMenuBar::removeMenu(QPlatformMenu *menu)
@ -69,6 +70,30 @@ void QAndroidPlatformMenuBar::removeMenu(QPlatformMenu *menu)
m_menus.erase(std::find(m_menus.begin(), m_menus.erase(std::find(m_menus.begin(),
m_menus.end(), m_menus.end(),
static_cast<QAndroidPlatformMenu *>(menu))); static_cast<QAndroidPlatformMenu *>(menu)));
int maxId = -1;
QHash<int, QPlatformMenu *>::iterator it = m_menuHash.begin();
while (it != m_menuHash.end()) {
if (it.value() == menu) {
it = m_menuHash.erase(it);
} else {
maxId = qMax(maxId, it.key());
++it;
}
}
m_nextMenuId = maxId + 1;
}
int QAndroidPlatformMenuBar::menuId(QPlatformMenu *menu) const
{
QHash<int, QPlatformMenu *>::const_iterator it;
for (it = m_menuHash.constBegin(); it != m_menuHash.constEnd(); ++it) {
if (it.value() == menu)
return it.key();
}
return -1;
} }
void QAndroidPlatformMenuBar::syncMenu(QPlatformMenu *menu) void QAndroidPlatformMenuBar::syncMenu(QPlatformMenu *menu)
@ -86,12 +111,17 @@ void QAndroidPlatformMenuBar::handleReparent(QWindow *newParentWindow)
QPlatformMenu *QAndroidPlatformMenuBar::menuForTag(quintptr tag) const QPlatformMenu *QAndroidPlatformMenuBar::menuForTag(quintptr tag) const
{ {
for (QPlatformMenu *menu : m_menus) { for (QAndroidPlatformMenu *menu : m_menus) {
if (menu->tag() == tag) if (menu->tag() == tag)
return menu; return menu;
} }
return 0; return nullptr;
}
QPlatformMenu *QAndroidPlatformMenuBar::menuForId(int menuId) const
{
return m_menuHash.value(menuId);
} }
QWindow *QAndroidPlatformMenuBar::parentWindow() const QWindow *QAndroidPlatformMenuBar::parentWindow() const

View File

@ -43,6 +43,7 @@
#include <qpa/qplatformmenu.h> #include <qpa/qplatformmenu.h>
#include <qvector.h> #include <qvector.h>
#include <qmutex.h> #include <qmutex.h>
#include <qhash.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -60,6 +61,8 @@ public:
void syncMenu(QPlatformMenu *menu) override; void syncMenu(QPlatformMenu *menu) override;
void handleReparent(QWindow *newParentWindow) override; void handleReparent(QWindow *newParentWindow) override;
QPlatformMenu *menuForTag(quintptr tag) const override; QPlatformMenu *menuForTag(quintptr tag) const override;
QPlatformMenu *menuForId(int menuId) const;
int menuId(QPlatformMenu *menu) const;
QWindow *parentWindow() const override; QWindow *parentWindow() const override;
PlatformMenusType menus() const; PlatformMenusType menus() const;
@ -69,6 +72,9 @@ private:
PlatformMenusType m_menus; PlatformMenusType m_menus;
QWindow *m_parentWindow; QWindow *m_parentWindow;
QMutex m_menusListMutex; QMutex m_menusListMutex;
int m_nextMenuId = 0;
QHash<int, QPlatformMenu *> m_menuHash;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -59,7 +59,6 @@
NSMenuItem *aboutItem; NSMenuItem *aboutItem;
NSMenuItem *aboutQtItem; NSMenuItem *aboutQtItem;
NSMenuItem *hideItem; NSMenuItem *hideItem;
NSMenuItem *lastAppSpecificItem;
NSMenuItem *servicesItem; NSMenuItem *servicesItem;
NSMenuItem *hideAllOthersItem; NSMenuItem *hideAllOthersItem;
NSMenuItem *showAllItem; NSMenuItem *showAllItem;
@ -118,6 +117,9 @@
[appMenu addItem:[NSMenuItem separatorItem]]; [appMenu addItem:[NSMenuItem separatorItem]];
// Preferences // Preferences
// We'll be adding app specific items after this. The macOS HIG state that,
// "In general, a Preferences menu item should be the first app-specific menu item."
// https://developer.apple.com/macos/human-interface-guidelines/menus/menu-bar-menus/
preferencesItem = [[QCocoaNSMenuItem alloc] init]; preferencesItem = [[QCocoaNSMenuItem alloc] init];
preferencesItem.title = @"Preferences…"; preferencesItem.title = @"Preferences…";
preferencesItem.keyEquivalent = @","; preferencesItem.keyEquivalent = @",";
@ -126,11 +128,6 @@
preferencesItem.hidden = YES; preferencesItem.hidden = YES;
[appMenu addItem:preferencesItem]; [appMenu addItem:preferencesItem];
// We'll be adding app specific items after this. The macOS HIG state that,
// "In general, a Preferences menu item should be the first app-specific menu item."
// https://developer.apple.com/macos/human-interface-guidelines/menus/menu-bar-menus/
lastAppSpecificItem = preferencesItem;
[appMenu addItem:[NSMenuItem separatorItem]]; [appMenu addItem:[NSMenuItem separatorItem]];
// Services item and menu // Services item and menu
@ -194,8 +191,6 @@
[showAllItem release]; [showAllItem release];
[quitItem release]; [quitItem release];
[lastAppSpecificItem release];
[super dealloc]; [super dealloc];
} }
@ -272,25 +267,20 @@
// No reason to create the item if it already exists. // No reason to create the item if it already exists.
for (NSMenuItem *item in appMenu.itemArray) for (NSMenuItem *item in appMenu.itemArray)
if (qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem == platformItem) if (qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem == platformItem)
return [[item retain] autorelease]; return item;
// Create an App-Specific menu item, insert it into the menu and return // Create an App-Specific menu item, insert it into the menu and return
// it as an autorelease item. // it as an autorelease item.
QCocoaNSMenuItem *item; QCocoaNSMenuItem *item;
if (platformItem->isSeparator()) if (platformItem->isSeparator())
item = [[QCocoaNSMenuItem separatorItemWithPlatformMenuItem:platformItem] retain]; item = [QCocoaNSMenuItem separatorItemWithPlatformMenuItem:platformItem];
else else
item = [[QCocoaNSMenuItem alloc] initWithPlatformMenuItem:platformItem]; item = [[[QCocoaNSMenuItem alloc] initWithPlatformMenuItem:platformItem] autorelease];
const auto location = [appMenu indexOfItem:lastAppSpecificItem]; const auto location = [self indexOfLastAppSpecificMenuItem];
[appMenu insertItem:item atIndex:NSInteger(location) + 1];
if (!lastAppSpecificItem.separatorItem) return item;
[lastAppSpecificItem release];
lastAppSpecificItem = item; // Keep track of this for later (i.e., don't release it)
[appMenu insertItem:item atIndex:location + 1];
return [[item retain] autorelease];
} }
- (void)orderFrontStandardAboutPanel:(id)sender - (void)orderFrontStandardAboutPanel:(id)sender
@ -344,8 +334,24 @@
- (NSArray<NSMenuItem *> *)mergeable - (NSArray<NSMenuItem *> *)mergeable
{ {
// Don't include the quitItem here, since we want it always visible and enabled regardless // Don't include the quitItem here, since we want it always visible and enabled regardless
// Note that lastAppSpecificItem may be nil, so we can't use @[] here. auto items = [NSArray arrayWithObjects:preferencesItem, aboutItem, aboutQtItem,
return [NSArray arrayWithObjects:preferencesItem, aboutItem, aboutQtItem, lastAppSpecificItem, nil]; appMenu.itemArray[[self indexOfLastAppSpecificMenuItem]], nil];
return items;
} }
- (NSUInteger)indexOfLastAppSpecificMenuItem
{
// Either the 'Preferences', which is the first app specific menu item, or something
// else we appended later (thus the reverse order):
const auto location = [appMenu.itemArray indexOfObjectWithOptions:NSEnumerationReverse
passingTest:^BOOL(NSMenuItem *item, NSUInteger, BOOL *) {
if (auto qtItem = qt_objc_cast<QCocoaNSMenuItem*>(item))
return qtItem != quitItem;
return NO;
}];
Q_ASSERT(location != NSNotFound);
return location;
}
@end @end

View File

@ -177,6 +177,9 @@ void *QCocoaNativeInterface::NSPrintInfoForPrintEngine(QPrintEngine *printEngine
QPixmap QCocoaNativeInterface::defaultBackgroundPixmapForQWizard() QPixmap QCocoaNativeInterface::defaultBackgroundPixmapForQWizard()
{ {
// Note: starting with macOS 10.14, the KeyboardSetupAssistant app bundle no
// longer contains the "Background.png" image. This function then returns a
// null pixmap.
const int ExpectedImageWidth = 242; const int ExpectedImageWidth = 242;
const int ExpectedImageHeight = 414; const int ExpectedImageHeight = 414;
QCFType<CFArrayRef> urls = LSCopyApplicationURLsForBundleIdentifier( QCFType<CFArrayRef> urls = LSCopyApplicationURLsForBundleIdentifier(

View File

@ -92,7 +92,8 @@ void QCocoaWindowManager::modalSessionChanged()
if (NSApp.modalWindow) { if (NSApp.modalWindow) {
// Lower window to that of the modal windows, but no less // Lower window to that of the modal windows, but no less
nativeWindow.level = NSModalPanelWindowLevel; nativeWindow.level = NSModalPanelWindowLevel;
[nativeWindow orderBack:nil]; if ([nativeWindow isVisible])
[nativeWindow orderBack:nil];
} else { } else {
// Restore window's natural window level, whatever that was // Restore window's natural window level, whatever that was
nativeWindow.level = naturalWindowLevel; nativeWindow.level = naturalWindowLevel;

View File

@ -3944,6 +3944,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
CGContextScaleCTM(ctx, -1, 1); CGContextScaleCTM(ctx, -1, 1);
CGContextTranslateCTM(ctx, -frameRect.left(), 0); CGContextTranslateCTM(ctx, -frameRect.left(), 0);
} else if (tabDirection == QMacStylePrivate::West && tp == QStyleOptionTab::Beginning) { } else if (tabDirection == QMacStylePrivate::West && tp == QStyleOptionTab::Beginning) {
CGContextTranslateCTM(ctx, 0, opt->rect.top());
CGContextScaleCTM(ctx, 1, -1); CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -frameRect.right()); CGContextTranslateCTM(ctx, 0, -frameRect.right());
} else if (tabDirection == QMacStylePrivate::East && tp == QStyleOptionTab::End) { } else if (tabDirection == QMacStylePrivate::East && tp == QStyleOptionTab::End) {

View File

@ -2890,7 +2890,7 @@ void QWizard::setPixmap(WizardPixmap which, const QPixmap &pixmap)
Returns the pixmap set for role \a which. Returns the pixmap set for role \a which.
By default, the only pixmap that is set is the BackgroundPixmap on By default, the only pixmap that is set is the BackgroundPixmap on
\macos. \macos version 10.13 and earlier.
\sa QWizardPage::pixmap(), {Elements of a Wizard Page} \sa QWizardPage::pixmap(), {Elements of a Wizard Page}
*/ */

View File

@ -84,6 +84,8 @@ private slots:
void operator_noteq(); void operator_noteq();
void resize(); void resize();
void fromBits_data();
void fromBits();
}; };
void tst_QBitArray::size_data() void tst_QBitArray::size_data()
@ -610,5 +612,60 @@ void tst_QBitArray::resize()
} }
void tst_QBitArray::fromBits_data()
{
QTest::addColumn<QByteArray>("data");
QTest::addColumn<int>("size");
QTest::addColumn<QBitArray>("expected");
QTest::newRow("empty") << QByteArray() << 0 << QBitArray();
auto add = [](const QByteArray &tag, const char *data) {
QTest::newRow(tag) << QByteArray(data, (tag.size() + 7) / 8) << tag.size()
<< QStringToQBitArray(tag);
};
// "0" to "0000000000000000"
for (int i = 1; i < 16; ++i) {
char zero[2] = { 0, 0 };
QByteArray pattern(i, '0');
add(pattern, zero);
}
// "1" to "1111111111111111"
for (int i = 1; i < 16; ++i) {
char one[2] = { '\xff', '\xff' };
QByteArray pattern(i, '1');
add(pattern, one);
}
// trailing 0 and 1
char zero = 1;
char one = 0;
QByteArray pzero = "1";
QByteArray pone = "0";
for (int i = 2; i < 8; ++i) {
zero <<= 1;
pzero.prepend('0');
add(pzero, &zero);
one = (one << 1) | 1;
pone.prepend('1');
add(pone, &one);
}
}
void tst_QBitArray::fromBits()
{
QFETCH(QByteArray, data);
QFETCH(int, size);
QFETCH(QBitArray, expected);
QBitArray fromBits = QBitArray::fromBits(data, size);
QCOMPARE(fromBits, expected);
QCOMPARE(QBitArray::fromBits(fromBits.bits(), fromBits.size()), expected);
}
QTEST_APPLESS_MAIN(tst_QBitArray) QTEST_APPLESS_MAIN(tst_QBitArray)
#include "tst_qbitarray.moc" #include "tst_qbitarray.moc"

View File

@ -36,6 +36,7 @@ class tst_QHighDpiScaling: public QObject
Q_OBJECT Q_OBJECT
private slots: private slots:
void factor();
void scale(); void scale();
}; };
@ -50,6 +51,23 @@ public:
QImage::Format format() const override { return QImage::Format_ARGB32_Premultiplied; } QImage::Format format() const override { return QImage::Format_ARGB32_Premultiplied; }
}; };
void tst_QHighDpiScaling::factor()
{
QHighDpiScaling::setGlobalFactor(2);
// Verfy that QHighDpiScaling::factor() does not crash on nullptr contexts.
QPoint fakeNativePosition = QPoint(5, 5);
QPlatformScreen *screenContext = nullptr;
QVERIFY(QHighDpiScaling::factor(screenContext) >= 0);
QVERIFY(QHighDpiScaling::factor(screenContext, &fakeNativePosition) >= 0);
QPlatformScreen *platformScreenContext = nullptr;
QVERIFY(QHighDpiScaling::factor(platformScreenContext) >= 0);
QVERIFY(QHighDpiScaling::factor(platformScreenContext, &fakeNativePosition) >= 0);
QWindow *windowContext = nullptr;
QVERIFY(QHighDpiScaling::factor(windowContext) >= 0);
QVERIFY(QHighDpiScaling::factor(windowContext, &fakeNativePosition) >= 0);
}
// QTBUG-77255: Test some scaling overloads // QTBUG-77255: Test some scaling overloads
void tst_QHighDpiScaling::scale() void tst_QHighDpiScaling::scale()
{ {

View File

@ -191,6 +191,7 @@ private slots:
void fontTagFace(); void fontTagFace();
void clearUndoRedoStacks();
private: private:
void backgroundImage_checkExpectedHtml(const QTextDocument &doc); void backgroundImage_checkExpectedHtml(const QTextDocument &doc);
void buildRegExpData(); void buildRegExpData();
@ -3522,5 +3523,16 @@ void tst_QTextDocument::fontTagFace()
} }
} }
void tst_QTextDocument::clearUndoRedoStacks()
{
QTextDocument doc;
QTextCursor c(&doc);
c.insertText(QStringLiteral("lorem ipsum"));
QVERIFY(doc.isUndoAvailable());
doc.clearUndoRedoStacks(QTextDocument::UndoStack); // Don't crash
QVERIFY(!doc.isUndoAvailable());
}
QTEST_MAIN(tst_QTextDocument) QTEST_MAIN(tst_QTextDocument)
#include "tst_qtextdocument.moc" #include "tst_qtextdocument.moc"

View File

@ -417,20 +417,19 @@ void tst_QWizard::setPixmap()
QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull()); QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull()); QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull()); QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull());
#ifdef Q_OS_OSX if (QSysInfo::macVersion() <= Q_MV_OSX(10, 13))
QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull()); QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
#else else
QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull()); QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull());
#endif
QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull()); QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull()); QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull()); QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull());
#ifdef Q_OS_OSX if (QSysInfo::macVersion() <= Q_MV_OSX(10, 13))
QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull()); QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
#else else
QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull()); QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
#endif
wizard.setPixmap(QWizard::BannerPixmap, p1); wizard.setPixmap(QWizard::BannerPixmap, p1);
wizard.setPixmap(QWizard::LogoPixmap, p2); wizard.setPixmap(QWizard::LogoPixmap, p2);
wizard.setPixmap(QWizard::WatermarkPixmap, p3); wizard.setPixmap(QWizard::WatermarkPixmap, p3);

View File

@ -88,7 +88,7 @@ static void sendMousePress(QWidget *widget, const QPoint &point, Qt::MouseButton
static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = 0) static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = 0)
{ {
QTest::mouseMove(widget, point); QTest::mouseMove(widget, point);
QMouseEvent event(QEvent::MouseMove, point, button, buttons, 0); QMouseEvent event(QEvent::MouseMove, point, widget->mapToGlobal(point), button, buttons, 0);
QApplication::sendEvent(widget, &event); QApplication::sendEvent(widget, &event);
QApplication::processEvents(); QApplication::processEvents();
} }