summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-08-12 13:23:11 +0200
committerLiang Qi <liang.qi@qt.io>2019-08-12 13:23:11 +0200
commit44c393f9b61797a240bfcbff1364ecdf7af41787 (patch)
tree94cca729399f5df23cf904f7bd866397d84aac7c
parentffc2d5722317fcab86865b11491d7bf7fef3e16d (diff)
parente66f247ccf345f1d303a92e53c21bb53d96c5af2 (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Conflicts: config.tests/arch/write_info.pri Repair architecture config test for the WASM_OBJECT_FILES=1 build mode configure.pri tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp Done-With: Jörg Bornemann <joerg.bornemann@qt.io> Change-Id: I9e12088356eb5bc65b53211cd7a8e330cccd1bb4
-rw-r--r--config.tests/arch/arch.pro1
-rw-r--r--config.tests/arch/arch_host.pro1
-rw-r--r--config.tests/arch/write_info.pri17
-rw-r--r--configure.pri32
-rw-r--r--mkspecs/features/mac/default_post.prf11
-rw-r--r--qmake/doc/src/qmake-manual.qdoc10
-rw-r--r--src/corelib/serialization/qjsonvalue.h4
-rw-r--r--src/corelib/tools/qbitarray.cpp12
-rw-r--r--src/corelib/tools/qcryptographichash.cpp8
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp35
-rw-r--r--src/gui/text/AGLFN_LICENSE.txt26
-rw-r--r--src/gui/text/qfontengine.cpp25
-rw-r--r--src/gui/text/qfontengine_p.h23
-rw-r--r--src/gui/text/qt_attribution.json17
-rw-r--r--src/gui/text/qtextdocument_p.cpp3
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp41
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h20
-rw-r--r--src/plugins/platforms/android/androidjnimenu.cpp12
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.cpp43
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.h5
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenubar.cpp34
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenubar.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm48
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindowmanager.mm3
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm1
-rw-r--r--src/widgets/dialogs/qwizard.cpp2
-rw-r--r--tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp57
-rw-r--r--tests/auto/gui/kernel/qhighdpiscaling/tst_qhighdpiscaling.cpp18
-rw-r--r--tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp12
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp19
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp2
33 files changed, 369 insertions, 184 deletions
diff --git a/config.tests/arch/arch.pro b/config.tests/arch/arch.pro
index 45a7eb33af..c607898b71 100644
--- a/config.tests/arch/arch.pro
+++ b/config.tests/arch/arch.pro
@@ -1 +1,2 @@
SOURCES = arch.cpp
+include(write_info.pri)
diff --git a/config.tests/arch/arch_host.pro b/config.tests/arch/arch_host.pro
index cefdbc77ef..ea0d1fa572 100644
--- a/config.tests/arch/arch_host.pro
+++ b/config.tests/arch/arch_host.pro
@@ -1,2 +1,3 @@
option(host_build)
SOURCES = arch.cpp
+include(write_info.pri)
diff --git a/config.tests/arch/write_info.pri b/config.tests/arch/write_info.pri
new file mode 100644
index 0000000000..79f980c873
--- /dev/null
+++ b/config.tests/arch/write_info.pri
@@ -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)
diff --git a/configure.pri b/configure.pri
index 7b8dee0953..cbd11c2f67 100644
--- a/configure.pri
+++ b/configure.pri
@@ -286,37 +286,13 @@ defineTest(qtConfTest_architecture) {
!qtConfTest_compile($${1}): \
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)
output = $$eval($${1}.output)
test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)/$$test
- test_out_file =
- for(ext, exts) {
- equals(ext, -): ext =
- f = $$test_out_dir/$$file_prefix$$output$$ext
- exists($$f) {
- test_out_file = $$f
- break()
- }
- }
- isEmpty(test_out_file): \
+ test_out_file = $$test_out_dir/$$cat($$test_out_dir/$${output}.target.txt)
+ exists($$test_out_file): \
+ content = $$cat($$test_out_file, blob)
+ else: \
error("$$eval($${1}.label) detection binary not found.")
content = $$cat($$test_out_file, blob)
diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf
index f34b305d08..60b2eb2117 100644
--- a/mkspecs/features/mac/default_post.prf
+++ b/mkspecs/features/mac/default_post.prf
@@ -1,5 +1,9 @@
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) {
!macx-xcode:if(isEmpty(BUILDS)|build_pass) {
# Detect changes to the platform SDK
@@ -14,7 +18,7 @@ contains(TEMPLATE, .*app) {
!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," \
- "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) {
# For Qt developers only
@@ -244,6 +248,11 @@ macx-xcode {
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)
!isEmpty(QMAKE_XCODE_VERSION): \
cache(QMAKE_XCODE_VERSION, stash)
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index b271abcee3..3495f97b2c 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -2583,10 +2583,8 @@
\section1 RC_FILE
- Specifies the name of the resource file for the application.
- The value of this variable is typically handled by
- qmake or \l{#QMAKESPEC}{qmake.conf} and rarely
- needs to be modified.
+ Windows only. Specifies the name of the Windows resource file (.rc) for the
+ target. See \l{Adding Windows Resource Files}.
\target RC_CODEPAGE
\section1 RC_CODEPAGE
@@ -2649,7 +2647,9 @@
\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
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely
needs to be modified.
diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h
index 0339eb59f7..5235ba1969 100644
--- a/src/corelib/serialization/qjsonvalue.h
+++ b/src/corelib/serialization/qjsonvalue.h
@@ -174,9 +174,9 @@ class Q_CORE_EXPORT QJsonValueRef
{
public:
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)
- : o(object), is_object(true), index(idx) {}
+ : o(object), is_object(true), index(static_cast<uint>(idx)) {}
inline operator QJsonValue() const { return toValue(); }
QJsonValueRef &operator = (const QJsonValue &val);
diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp
index 4952090620..f0b81cce66 100644
--- a/src/corelib/tools/qbitarray.cpp
+++ b/src/corelib/tools/qbitarray.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** 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
* 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
- * 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:
* 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 result;
+ if (size == 0)
+ return result;
qsizetype nbytes = (size + 7) / 8;
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
if (size & 7)
- bits[nbytes] &= 0xffU >> (size & 7);
+ bits[nbytes] &= 0xffU >> (8 - (size & 7));
*bits = result.d.size() * 8 - size;
return result;
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index 3c79bb797d..51f48503fb 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -387,19 +387,19 @@ void QCryptographicHash::addData(const char *data, int length)
break;
case RealSha3_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;
case RealSha3_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;
case RealSha3_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;
case RealSha3_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;
#endif
}
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 0fea416404..64f1397771 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -456,6 +456,8 @@ QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QPlatformS
{
if (!m_active)
return { qreal(1), QPoint() };
+ if (!platformScreen)
+ return { m_factor, QPoint() }; // the global factor
const QPlatformScreen *actualScreen = nativePosition ?
platformScreen->screenForPosition(*nativePosition) : platformScreen;
return { m_factor * screenSubfactor(actualScreen), actualScreen->geometry().topLeft() };
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 4b06afd4eb..5bdf3299c9 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2908,19 +2908,34 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
for (int i = 0; i < numGlyphs; i++) {
QFixed spp = fontEngine->subPixelPositionForX(positions[i].x);
- QPoint offset;
- const QImage *alphaMap = fontEngine->lockedAlphaMapForGlyph(glyphs[i], spp, neededFormat, s->matrix,
- &offset);
- if (alphaMap == 0 || alphaMap->isNull())
+ const QFontEngine::Glyph *alphaMap = fontEngine->glyphData(glyphs[i], spp, neededFormat, s->matrix);
+ if (!alphaMap)
continue;
- alphaPenBlt(alphaMap->constBits(), alphaMap->bytesPerLine(), alphaMap->depth(),
- qFloor(positions[i].x) + offset.x(),
- qRound(positions[i].y) + offset.y(),
- alphaMap->width(), alphaMap->height(),
+ int depth;
+ int bytesPerLine;
+ switch (alphaMap->format) {
+ case QFontEngine::Format_Mono:
+ 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();
+ };
+
+ alphaPenBlt(alphaMap->data, bytesPerLine, depth,
+ qFloor(positions[i].x) + alphaMap->x,
+ qRound(positions[i].y) - alphaMap->y,
+ alphaMap->width, alphaMap->height,
fontEngine->expectsGammaCorrectedBlending());
-
- fontEngine->unlockAlphaMapForGlyph();
}
} else {
diff --git a/src/gui/text/AGLFN_LICENSE.txt b/src/gui/text/AGLFN_LICENSE.txt
new file mode 100644
index 0000000000..50abffca15
--- /dev/null
+++ b/src/gui/text/AGLFN_LICENSE.txt
@@ -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.
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index e435177843..e59d425cb6 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -923,29 +923,10 @@ QFixed QFontEngine::subPixelPositionForX(QFixed x) const
return subPixelPosition;
}
-QImage *QFontEngine::lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition,
- QFontEngine::GlyphFormat neededFormat,
- const QTransform &t, QPoint *offset)
+QFontEngine::Glyph *QFontEngine::glyphData(glyph_t, QFixed,
+ QFontEngine::GlyphFormat, const QTransform &)
{
- Q_ASSERT(currentlyLockedAlphaMap.isNull());
- 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();
+ return nullptr;
}
QImage QFontEngine::alphaMapForGlyph(glyph_t glyph)
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 682395ece6..48dcdbeff7 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -124,6 +124,22 @@ public:
};
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();
inline Type type() const { return m_type; }
@@ -191,11 +207,7 @@ public:
virtual QImage alphaMapForGlyph(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 *lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition,
- GlyphFormat neededFormat,
- const QTransform &t = QTransform(),
- QPoint *offset = 0);
- virtual void unlockAlphaMapForGlyph();
+ virtual Glyph *glyphData(glyph_t glyph, QFixed subPixelPosition, GlyphFormat neededFormat, const QTransform &t);
virtual bool hasInternalCaching() const { return false; }
virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/)
@@ -346,7 +358,6 @@ public:
void loadKerningPairs(QFixed scalingFactor);
GlyphFormat glyphFormat;
- QImage currentlyLockedAlphaMap;
int m_subPixelPositionCount; // Number of positions within a single pixel for this cache
inline QVariant userData() const { return m_userData; }
diff --git a/src/gui/text/qt_attribution.json b/src/gui/text/qt_attribution.json
new file mode 100644
index 0000000000..c3a57267e2
--- /dev/null
+++ b/src/gui/text/qt_attribution.json
@@ -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"
+ }
+]
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index c0a0c1a177..6e535c12b3 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -1103,12 +1103,11 @@ void QTextDocumentPrivate::clearUndoRedoStacks(QTextDocument::Stacks stacksToCle
bool redoCommandsAvailable = undoState != undoStack.size();
if (stacksToClear == QTextDocument::UndoStack && undoCommandsAvailable) {
for (int i = 0; i < undoState; ++i) {
- QTextUndoCommand c = undoStack.at(undoState);
+ QTextUndoCommand c = undoStack.at(i);
if (c.command & QTextUndoCommand::Custom)
delete c.custom;
}
undoStack.remove(0, undoState);
- undoStack.resize(undoStack.size() - undoState);
undoState = 0;
if (emitSignals)
emitUndoAvailable(false);
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index 2aef71a418..08e652b2a0 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -106,7 +106,7 @@ static bool ft_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *leng
return result;
}
-static QFontEngineFT::Glyph emptyGlyph = {0, 0, 0, 0, 0, 0, 0, 0};
+static QFontEngineFT::Glyph emptyGlyph;
static const QFontEngine::HintStyle ftInitialDefaultHintStyle =
#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);
}
-QFontEngineFT::Glyph::~Glyph()
-{
- delete [] data;
-}
-
struct LcdFilterDummy
{
static inline void filterPixel(uchar &, uchar &, uchar &)
@@ -1986,11 +1981,10 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng
return img;
}
-QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixelPosition,
- QFontEngine::GlyphFormat neededFormat,
- const QTransform &t, QPoint *offset)
+QFontEngine::Glyph *QFontEngineFT::glyphData(glyph_t glyphIndex, QFixed subPixelPosition,
+ QFontEngine::GlyphFormat neededFormat, const QTransform &t)
{
- Q_ASSERT(currentlyLockedAlphaMap.isNull());
+ Q_ASSERT(cacheEnabled);
if (isBitmapFont())
neededFormat = Format_Mono;
@@ -2000,33 +1994,10 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe
neededFormat = Format_A8;
Glyph *glyph = loadGlyphFor(glyphIndex, subPixelPosition, neededFormat, t);
-
- 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)
+ if (!glyph || !glyph->width || !glyph->height)
return nullptr;
- if (currentlyLockedAlphaMap.isNull())
- return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset);
-
- QImageData *data = currentlyLockedAlphaMap.data_ptr();
- data->is_locked = true;
-
- return &currentlyLockedAlphaMap;
-}
-
-void QFontEngineFT::unlockAlphaMapForGlyph()
-{
- QFontEngine::unlockAlphaMapForGlyph();
+ return glyph;
}
static inline bool is2dRotation(const QTransform &t)
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
index 109bae86e9..2863d206d2 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
@@ -129,20 +129,6 @@ private:
class QFontEngineFT : public QFontEngine
{
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 {
int linearAdvance;
unsigned short width;
@@ -241,11 +227,9 @@ private:
QFixed subPixelPosition,
const QTransform &matrix,
QFontEngine::GlyphFormat format) override;
- QImage *lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition,
- GlyphFormat neededFormat, const QTransform &t,
- QPoint *offset) override;
+ Glyph *glyphData(glyph_t glyph, QFixed subPixelPosition,
+ GlyphFormat neededFormat, const QTransform &t) override;
bool hasInternalCaching() const override { return cacheEnabled; }
- void unlockAlphaMapForGlyph() override;
bool expectsGammaCorrectedBlending() const override;
void removeGlyphFromCache(glyph_t glyph) override;
diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp
index 6f548aba52..e9359def0f 100644
--- a/src/plugins/platforms/android/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/androidjnimenu.cpp
@@ -225,10 +225,11 @@ namespace QtAndroidMenu
QString itemText = removeAmpersandEscapes(item->text());
jstring jtext = env->NewString(reinterpret_cast<const jchar *>(itemText.data()),
itemText.length());
+ jint menuId = platformMenu->menuId(item);
jobject menuItem = env->CallObjectMethod(menu,
addMenuItemMethodID,
menuNoneValue,
- int(item->tag()),
+ menuId,
order++,
jtext);
env->DeleteLocalRef(jtext);
@@ -262,10 +263,11 @@ namespace QtAndroidMenu
QString itemText = removeAmpersandEscapes(item->text());
jstring jtext = env->NewString(reinterpret_cast<const jchar *>(itemText.data()),
itemText.length());
+ jint menuId = visibleMenuBar->menuId(item);
jobject menuItem = env->CallObjectMethod(menu,
addMenuItemMethodID,
menuNoneValue,
- int(item->tag()),
+ menuId,
order++,
jtext);
env->DeleteLocalRef(jtext);
@@ -290,7 +292,7 @@ namespace QtAndroidMenu
const QAndroidPlatformMenuBar::PlatformMenusType &menus = visibleMenuBar->menus();
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->menu()) {
showContextMenu(item->menu(), QRect(), env);
@@ -301,7 +303,7 @@ namespace QtAndroidMenu
}
}
} else {
- QAndroidPlatformMenu *menu = static_cast<QAndroidPlatformMenu *>(visibleMenuBar->menuForTag(menuId));
+ QAndroidPlatformMenu *menu = static_cast<QAndroidPlatformMenu *>(visibleMenuBar->menuForId(menuId));
if (menu)
showContextMenu(menu, QRect(), env);
}
@@ -341,7 +343,7 @@ namespace QtAndroidMenu
static jboolean onContextItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked)
{
QMutexLocker lock(&visibleMenuMutex);
- QAndroidPlatformMenuItem * item = static_cast<QAndroidPlatformMenuItem *>(visibleMenu->menuItemForTag(menuId));
+ QAndroidPlatformMenuItem * item = static_cast<QAndroidPlatformMenuItem *>(visibleMenu->menuItemForId(menuId));
if (item) {
if (item->menu()) {
showContextMenu(item->menu(), QRect(), env);
diff --git a/src/plugins/platforms/android/qandroidplatformmenu.cpp b/src/plugins/platforms/android/qandroidplatformmenu.cpp
index d9cecebf2c..7ce603831f 100644
--- a/src/plugins/platforms/android/qandroidplatformmenu.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenu.cpp
@@ -62,6 +62,7 @@ void QAndroidPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatform
m_menuItems.end(),
static_cast<QAndroidPlatformMenuItem *>(before)),
static_cast<QAndroidPlatformMenuItem *>(menuItem));
+ m_menuHash.insert(m_nextMenuId++, menuItem);
}
void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
@@ -72,6 +73,21 @@ void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
static_cast<QAndroidPlatformMenuItem *>(menuItem));
if (it != m_menuItems.end())
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)
@@ -139,6 +155,16 @@ void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &t
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
{
if (position < m_menuItems.size())
@@ -146,13 +172,20 @@ QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const
return 0;
}
-QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const
+int QAndroidPlatformMenu::menuId(QPlatformMenuItem *menu) const
{
- for (QPlatformMenuItem *menuItem : m_menuItems) {
- if (menuItem->tag() == tag)
- return menuItem;
+ QHash<int, QPlatformMenuItem *>::const_iterator it;
+ for (it = m_menuHash.constBegin(); it != m_menuHash.constEnd(); ++it) {
+ 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
diff --git a/src/plugins/platforms/android/qandroidplatformmenu.h b/src/plugins/platforms/android/qandroidplatformmenu.h
index 47e650f2d7..b1d6a88787 100644
--- a/src/plugins/platforms/android/qandroidplatformmenu.h
+++ b/src/plugins/platforms/android/qandroidplatformmenu.h
@@ -73,6 +73,8 @@ public:
QPlatformMenuItem *menuItemAt(int position) const override;
QPlatformMenuItem *menuItemForTag(quintptr tag) const override;
+ QPlatformMenuItem *menuItemForId(int menuId) const;
+ int menuId(QPlatformMenuItem *menuItem) const;
PlatformMenuItemsType menuItems() const;
QMutex *menuItemsMutex();
@@ -84,6 +86,9 @@ private:
bool m_enabled;
bool m_isVisible;
QMutex m_menuItemsMutex;
+
+ int m_nextMenuId = 0;
+ QHash<int, QPlatformMenuItem *> m_menuHash;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/qandroidplatformmenubar.cpp
index 35930f0628..7c6299b4b7 100644
--- a/src/plugins/platforms/android/qandroidplatformmenubar.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenubar.cpp
@@ -61,6 +61,7 @@ void QAndroidPlatformMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *bef
m_menus.end(),
static_cast<QAndroidPlatformMenu *>(before)),
static_cast<QAndroidPlatformMenu *>(menu));
+ m_menuHash.insert(m_nextMenuId++, 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.end(),
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)
@@ -86,12 +111,17 @@ void QAndroidPlatformMenuBar::handleReparent(QWindow *newParentWindow)
QPlatformMenu *QAndroidPlatformMenuBar::menuForTag(quintptr tag) const
{
- for (QPlatformMenu *menu : m_menus) {
+ for (QAndroidPlatformMenu *menu : m_menus) {
if (menu->tag() == tag)
return menu;
}
- return 0;
+ return nullptr;
+}
+
+QPlatformMenu *QAndroidPlatformMenuBar::menuForId(int menuId) const
+{
+ return m_menuHash.value(menuId);
}
QWindow *QAndroidPlatformMenuBar::parentWindow() const
diff --git a/src/plugins/platforms/android/qandroidplatformmenubar.h b/src/plugins/platforms/android/qandroidplatformmenubar.h
index f5935b8177..81a26c72f4 100644
--- a/src/plugins/platforms/android/qandroidplatformmenubar.h
+++ b/src/plugins/platforms/android/qandroidplatformmenubar.h
@@ -43,6 +43,7 @@
#include <qpa/qplatformmenu.h>
#include <qvector.h>
#include <qmutex.h>
+#include <qhash.h>
QT_BEGIN_NAMESPACE
@@ -60,6 +61,8 @@ public:
void syncMenu(QPlatformMenu *menu) override;
void handleReparent(QWindow *newParentWindow) override;
QPlatformMenu *menuForTag(quintptr tag) const override;
+ QPlatformMenu *menuForId(int menuId) const;
+ int menuId(QPlatformMenu *menu) const;
QWindow *parentWindow() const override;
PlatformMenusType menus() const;
@@ -69,6 +72,9 @@ private:
PlatformMenusType m_menus;
QWindow *m_parentWindow;
QMutex m_menusListMutex;
+
+ int m_nextMenuId = 0;
+ QHash<int, QPlatformMenu *> m_menuHash;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index da0fc5c6a1..d384078e91 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -59,7 +59,6 @@
NSMenuItem *aboutItem;
NSMenuItem *aboutQtItem;
NSMenuItem *hideItem;
- NSMenuItem *lastAppSpecificItem;
NSMenuItem *servicesItem;
NSMenuItem *hideAllOthersItem;
NSMenuItem *showAllItem;
@@ -118,6 +117,9 @@
[appMenu addItem:[NSMenuItem separatorItem]];
// 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.title = @"Preferences…";
preferencesItem.keyEquivalent = @",";
@@ -126,11 +128,6 @@
preferencesItem.hidden = YES;
[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]];
// Services item and menu
@@ -194,8 +191,6 @@
[showAllItem release];
[quitItem release];
- [lastAppSpecificItem release];
-
[super dealloc];
}
@@ -272,25 +267,20 @@
// No reason to create the item if it already exists.
for (NSMenuItem *item in appMenu.itemArray)
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
// it as an autorelease item.
QCocoaNSMenuItem *item;
if (platformItem->isSeparator())
- item = [[QCocoaNSMenuItem separatorItemWithPlatformMenuItem:platformItem] retain];
+ item = [QCocoaNSMenuItem separatorItemWithPlatformMenuItem:platformItem];
else
- item = [[QCocoaNSMenuItem alloc] initWithPlatformMenuItem:platformItem];
-
- const auto location = [appMenu indexOfItem:lastAppSpecificItem];
+ item = [[[QCocoaNSMenuItem alloc] initWithPlatformMenuItem:platformItem] autorelease];
- if (!lastAppSpecificItem.separatorItem)
- [lastAppSpecificItem release];
- lastAppSpecificItem = item; // Keep track of this for later (i.e., don't release it)
+ const auto location = [self indexOfLastAppSpecificMenuItem];
+ [appMenu insertItem:item atIndex:NSInteger(location) + 1];
- [appMenu insertItem:item atIndex:location + 1];
-
- return [[item retain] autorelease];
+ return item;
}
- (void)orderFrontStandardAboutPanel:(id)sender
@@ -344,8 +334,24 @@
- (NSArray<NSMenuItem *> *)mergeable
{
// 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.
- return [NSArray arrayWithObjects:preferencesItem, aboutItem, aboutQtItem, lastAppSpecificItem, nil];
+ auto items = [NSArray arrayWithObjects:preferencesItem, aboutItem, aboutQtItem,
+ 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
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 7979e430ac..9bd19dd07c 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -177,6 +177,9 @@ void *QCocoaNativeInterface::NSPrintInfoForPrintEngine(QPrintEngine *printEngine
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 ExpectedImageHeight = 414;
QCFType<CFArrayRef> urls = LSCopyApplicationURLsForBundleIdentifier(
diff --git a/src/plugins/platforms/cocoa/qcocoawindowmanager.mm b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm
index 879bfaa546..9c45d8c7fc 100644
--- a/src/plugins/platforms/cocoa/qcocoawindowmanager.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm
@@ -92,7 +92,8 @@ void QCocoaWindowManager::modalSessionChanged()
if (NSApp.modalWindow) {
// Lower window to that of the modal windows, but no less
nativeWindow.level = NSModalPanelWindowLevel;
- [nativeWindow orderBack:nil];
+ if ([nativeWindow isVisible])
+ [nativeWindow orderBack:nil];
} else {
// Restore window's natural window level, whatever that was
nativeWindow.level = naturalWindowLevel;
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 2717a40762..62f089b654 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -3944,6 +3944,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
CGContextScaleCTM(ctx, -1, 1);
CGContextTranslateCTM(ctx, -frameRect.left(), 0);
} else if (tabDirection == QMacStylePrivate::West && tp == QStyleOptionTab::Beginning) {
+ CGContextTranslateCTM(ctx, 0, opt->rect.top());
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -frameRect.right());
} else if (tabDirection == QMacStylePrivate::East && tp == QStyleOptionTab::End) {
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index 88b187cd7f..f6f540f57c 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -2890,7 +2890,7 @@ void QWizard::setPixmap(WizardPixmap which, const QPixmap &pixmap)
Returns the pixmap set for role \a which.
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}
*/
diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
index d19eac7530..9a7c099228 100644
--- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
+++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
@@ -84,6 +84,8 @@ private slots:
void operator_noteq();
void resize();
+ void fromBits_data();
+ void fromBits();
};
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)
#include "tst_qbitarray.moc"
diff --git a/tests/auto/gui/kernel/qhighdpiscaling/tst_qhighdpiscaling.cpp b/tests/auto/gui/kernel/qhighdpiscaling/tst_qhighdpiscaling.cpp
index 969b2351ec..ec80c2d02c 100644
--- a/tests/auto/gui/kernel/qhighdpiscaling/tst_qhighdpiscaling.cpp
+++ b/tests/auto/gui/kernel/qhighdpiscaling/tst_qhighdpiscaling.cpp
@@ -36,6 +36,7 @@ class tst_QHighDpiScaling: public QObject
Q_OBJECT
private slots:
+ void factor();
void scale();
};
@@ -50,6 +51,23 @@ public:
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
void tst_QHighDpiScaling::scale()
{
diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
index 591fafc7fb..58810f73c1 100644
--- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
+++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
@@ -191,6 +191,7 @@ private slots:
void fontTagFace();
+ void clearUndoRedoStacks();
private:
void backgroundImage_checkExpectedHtml(const QTextDocument &doc);
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)
#include "tst_qtextdocument.moc"
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
index 63f6e67a3e..da75e64d1e 100644
--- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -417,20 +417,19 @@ void tst_QWizard::setPixmap()
QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull());
-#ifdef Q_OS_OSX
- QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
-#else
- QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull());
-#endif
+ if (QSysInfo::macVersion() <= Q_MV_OSX(10, 13))
+ QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
+ else
+ QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull());
QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull());
-#ifdef Q_OS_OSX
- QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
-#else
- QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
-#endif
+ if (QSysInfo::macVersion() <= Q_MV_OSX(10, 13))
+ QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
+ else
+ QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
+
wizard.setPixmap(QWizard::BannerPixmap, p1);
wizard.setPixmap(QWizard::LogoPixmap, p2);
wizard.setPixmap(QWizard::WatermarkPixmap, p3);
diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
index a9c1404891..1442219bea 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp
@@ -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)
{
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::processEvents();
}