Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"

This commit is contained in:
Lars Knoll 2020-02-27 14:22:01 +01:00
commit bb802b4318
17 changed files with 128 additions and 38 deletions

View File

@ -17,7 +17,7 @@ include(g++-base.conf)
MAKEFILE_GENERATOR = MINGW MAKEFILE_GENERATOR = MINGW
QMAKE_PLATFORM = win32 mingw QMAKE_PLATFORM = win32 mingw
CONFIG += precompile_header CONFIG += debug_and_release debug_and_release_target precompile_header
DEFINES += UNICODE _UNICODE WIN32 MINGW_HAS_SECURE_API=1 DEFINES += UNICODE _UNICODE WIN32 MINGW_HAS_SECURE_API=1
QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32 QMAKE_COMPILER_DEFINES += __GNUC__ _WIN32
# can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for # can't add 'DEFINES += WIN64' and 'QMAKE_COMPILER_DEFINES += _WIN64' defines for

View File

@ -60,7 +60,7 @@ win32|CONFIG(static, static|shared) {
"QMAKE_DEFINES_$${ucmodule} = $$val_escape(MODULE_DEFINES)" "QMAKE_DEFINES_$${ucmodule} = $$val_escape(MODULE_DEFINES)"
android { android {
MODULE_PRI_CONT += "QMAKE_LIBS_$${ucmodule} =" MODULE_PRI_CONT += "QMAKE_LIBS_$${ucmodule} ="
} else: debug_and_release { } else: qtConfig(debug_and_release): {
win32: \ win32: \
MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}d.$$suffix MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}d.$$suffix
else: darwin: \ else: darwin: \

View File

@ -285,11 +285,15 @@ namespace QtPrivate {
{ {
}; };
template <typename T>
using is_bool = std::is_same<bool, typename std::decay<T>::type>;
template<typename From, typename To> template<typename From, typename To>
struct AreArgumentsNarrowedBase<From, To, typename std::enable_if<sizeof(From) && sizeof(To)>::type> struct AreArgumentsNarrowedBase<From, To, typename std::enable_if<sizeof(From) && sizeof(To)>::type>
: std::integral_constant<bool, : std::integral_constant<bool,
(std::is_floating_point<From>::value && std::is_integral<To>::value) || (std::is_floating_point<From>::value && std::is_integral<To>::value) ||
(std::is_floating_point<From>::value && std::is_floating_point<To>::value && sizeof(From) > sizeof(To)) || (std::is_floating_point<From>::value && std::is_floating_point<To>::value && sizeof(From) > sizeof(To)) ||
((std::is_pointer<From>::value || std::is_member_pointer<From>::value) && QtPrivate::is_bool<To>::value) ||
((std::is_integral<From>::value || std::is_enum<From>::value) && std::is_floating_point<To>::value) || ((std::is_integral<From>::value || std::is_enum<From>::value) && std::is_floating_point<To>::value) ||
(std::is_integral<From>::value && std::is_integral<To>::value (std::is_integral<From>::value && std::is_integral<To>::value
&& (sizeof(From) > sizeof(To) && (sizeof(From) > sizeof(To)

View File

@ -663,6 +663,9 @@ glyph_metrics_t QFontEngine::tightBoundingBox(const QGlyphLayout &glyphs)
QFixed ymax = 0; QFixed ymax = 0;
QFixed xmax = 0; QFixed xmax = 0;
for (int i = 0; i < glyphs.numGlyphs; i++) { for (int i = 0; i < glyphs.numGlyphs; i++) {
// If shaping has found this should be ignored, ignore it.
if (!glyphs.advances[i] || glyphs.attributes[i].dontPrint)
continue;
glyph_metrics_t bb = boundingBox(glyphs.glyphs[i]); glyph_metrics_t bb = boundingBox(glyphs.glyphs[i]);
QFixed x = overall.xoff + glyphs.offsets[i].x + bb.x; QFixed x = overall.xoff + glyphs.offsets[i].x + bb.x;
QFixed y = overall.yoff + glyphs.offsets[i].y + bb.y; QFixed y = overall.yoff + glyphs.offsets[i].y + bb.y;

View File

@ -712,9 +712,8 @@ struct QBidiAlgorithm {
analysis[pos].bidiDirection = QChar::DirEN; analysis[pos].bidiDirection = QChar::DirEN;
++it; ++it;
} }
} else {
lastETPosition.clear();
} }
lastETPosition.clear();
} }
last = current; last = current;
lastPos = pos; lastPos = pos;

View File

@ -1678,6 +1678,9 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
QFixed ymax = 0; QFixed ymax = 0;
QFixed xmax = 0; QFixed xmax = 0;
for (int i = 0; i < glyphs.numGlyphs; i++) { for (int i = 0; i < glyphs.numGlyphs; i++) {
// If shaping has found this should be ignored, ignore it.
if (!glyphs.advances[i] || glyphs.attributes[i].dontPrint)
continue;
Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs.glyphs[i]) : nullptr; Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs.glyphs[i]) : nullptr;
if (!g) { if (!g) {
if (!face) if (!face)

View File

@ -36,7 +36,7 @@
#include <QtGui/qpainter.h> #include <QtGui/qpainter.h>
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>
#include <qpa/qplatformscreen.h> #include <qpa/qplatformscreen.h>
#include <QtGui/qoffscreensurface.h>
#include <QtGui/qbackingstore.h> #include <QtGui/qbackingstore.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -53,12 +53,29 @@ QWasmBackingStore::QWasmBackingStore(QWasmCompositor *compositor, QWindow *windo
QWasmBackingStore::~QWasmBackingStore() QWasmBackingStore::~QWasmBackingStore()
{ {
auto window = this->window();
QWasmIntegration::get()->removeBackingStore(window);
destroy();
QWasmWindow *wasmWindow = static_cast<QWasmWindow *>(window->handle());
if (wasmWindow)
wasmWindow->setBackingStore(nullptr);
} }
void QWasmBackingStore::destroy() void QWasmBackingStore::destroy()
{ {
if (m_texture->isCreated()) if (m_texture->isCreated()) {
m_texture->destroy(); auto context = m_compositor->context();
auto currentContext = QOpenGLContext::currentContext();
if (!currentContext || !QOpenGLContext::areSharing(context, currentContext)) {
QOffscreenSurface offScreenSurface(m_compositor->screen()->screen());
offScreenSurface.setFormat(context->format());
offScreenSurface.create();
context->makeCurrent(&offScreenSurface);
m_texture->destroy();
} else {
m_texture->destroy();
}
}
} }
QPaintDevice *QWasmBackingStore::paintDevice() QPaintDevice *QWasmBackingStore::paintDevice()
@ -81,9 +98,9 @@ void QWasmBackingStore::updateTexture()
if (m_dirty.isNull()) if (m_dirty.isNull())
return; return;
if (m_recreateTexture && m_texture->isCreated()) { if (m_recreateTexture) {
m_recreateTexture = false; m_recreateTexture = false;
m_texture->destroy(); destroy();
} }
if (!m_texture->isCreated()) { if (!m_texture->isCreated()) {

View File

@ -59,7 +59,6 @@ QWasmCompositedWindow::QWasmCompositedWindow()
QWasmCompositor::QWasmCompositor(QWasmScreen *screen) QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
:QObject(screen) :QObject(screen)
, m_frameBuffer(nullptr)
, m_blitter(new QOpenGLTextureBlitter) , m_blitter(new QOpenGLTextureBlitter)
, m_needComposit(false) , m_needComposit(false)
, m_inFlush(false) , m_inFlush(false)
@ -71,7 +70,6 @@ QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
QWasmCompositor::~QWasmCompositor() QWasmCompositor::~QWasmCompositor()
{ {
delete m_frameBuffer;
destroy(); destroy();
} }
@ -748,3 +746,8 @@ QWasmScreen *QWasmCompositor::screen()
{ {
return static_cast<QWasmScreen *>(parent()); return static_cast<QWasmScreen *>(parent());
} }
QOpenGLContext *QWasmCompositor::context()
{
return m_context.data();
}

View File

@ -125,11 +125,13 @@ public:
static QWasmTitleBarOptions makeTitleBarOptions(const QWasmWindow *window); static QWasmTitleBarOptions makeTitleBarOptions(const QWasmWindow *window);
static QRect titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::SubControls subcontrol); static QRect titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::SubControls subcontrol);
QWasmScreen *screen();
QOpenGLContext *context();
private slots: private slots:
void frame(); void frame();
private: private:
QWasmScreen *screen();
void notifyTopWindowChanged(QWasmWindow *window); void notifyTopWindowChanged(QWasmWindow *window);
void drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window); void drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
void drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window); void drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
@ -138,7 +140,6 @@ private:
void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window); void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
void drwPanelButton(); void drwPanelButton();
QImage *m_frameBuffer;
QScopedPointer<QOpenGLContext> m_context; QScopedPointer<QOpenGLContext> m_context;
QScopedPointer<QOpenGLTextureBlitter> m_blitter; QScopedPointer<QOpenGLTextureBlitter> m_blitter;

View File

@ -187,6 +187,11 @@ QPlatformBackingStore *QWasmIntegration::createPlatformBackingStore(QWindow *win
#endif #endif
} }
void QWasmIntegration::removeBackingStore(QWindow* window)
{
m_backingStores.remove(window);
}
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QWasmIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const QPlatformOpenGLContext *QWasmIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{ {

View File

@ -89,6 +89,7 @@ public:
void resizeScreen(const emscripten::val &canvas); void resizeScreen(const emscripten::val &canvas);
void resizeAllScreens(); void resizeAllScreens();
void updateDpi(); void updateDpi();
void removeBackingStore(QWindow* window);
private: private:
mutable QWasmFontDatabase *m_fontDb; mutable QWasmFontDatabase *m_fontDb;

View File

@ -183,7 +183,7 @@
Run the installer, Run the installer,
select custom installation and install the MySQL C Connector select custom installation and install the MySQL C Connector
which matches your Qt installation (x86 or x64). which matches your Qt installation (x86 or x64).
After installation make sure that the needed files are there: After installation check that the needed files are there:
\list \list
\li \c {<MySQL dir>/lib/libmysql.lib} \li \c {<MySQL dir>/lib/libmysql.lib}
\li \c {<MySQL dir>/lib/libmysql.dll} \li \c {<MySQL dir>/lib/libmysql.dll}
@ -196,16 +196,20 @@
\li \c {<MariaDB dir>/include/mysql.h} \li \c {<MariaDB dir>/include/mysql.h}
\endlist \endlist
Build the plugin as follows (here it is assumed that the MySQL \note As of MySQL 8.0.19, the C Connector is no longer offered as a standalone
C Connector is installed in installable component. Instead, you can get \c{mysql.h} and \c{libmysql.*} by
installing the full MySQL Server (x64 only) or the
\l{https://downloads.mariadb.org/connector-c/}{MariaDB C Connector}.
Build the plugin as follows (here it is assumed that \c{<MySQL dir>} is
\c{C:/Program Files/MySQL/MySQL Connector C 6.1}): \c{C:/Program Files/MySQL/MySQL Connector C 6.1}):
\snippet code/doc_src_sql-driver.qdoc 5 \snippet code/doc_src_sql-driver.qdoc 5
If you are not using a Microsoft compiler, replace \c nmake with \c If you are not using a Microsoft compiler, replace \c nmake with \c
mingw32-make in the line above. mingw32-make above.
When you distribute your application, remember to include libmysql.dll / libmariadb.dll When you distribute your application, remember to include \e libmysql.dll / \e libmariadb.dll
in your installation package. It must be placed in the same folder in your installation package. It must be placed in the same folder
as the application executable. \e libmysql.dll additionally needs the as the application executable. \e libmysql.dll additionally needs the
MSVC runtime libraries which can be installed with MSVC runtime libraries which can be installed with

View File

@ -677,7 +677,8 @@ void QDateTimeEdit::setTimeRange(const QTime &min, const QTime &max)
\brief The currently displayed fields of the date time edit. \brief The currently displayed fields of the date time edit.
Returns a bit set of the displayed sections for this format. Returns a bit set of the displayed sections for this format.
\a setDisplayFormat(), displayFormat()
\sa setDisplayFormat(), displayFormat()
*/ */
QDateTimeEdit::Sections QDateTimeEdit::displayedSections() const QDateTimeEdit::Sections QDateTimeEdit::displayedSections() const
@ -690,7 +691,8 @@ QDateTimeEdit::Sections QDateTimeEdit::displayedSections() const
\property QDateTimeEdit::currentSection \property QDateTimeEdit::currentSection
\brief The current section of the spinbox. \brief The current section of the spinbox.
\a setCurrentSection()
\sa setCurrentSection()
*/ */
QDateTimeEdit::Section QDateTimeEdit::currentSection() const QDateTimeEdit::Section QDateTimeEdit::currentSection() const
@ -770,8 +772,7 @@ int QDateTimeEdit::sectionCount() const
the cursorPosition is 5, currentSectionIndex returns 1. If the the cursorPosition is 5, currentSectionIndex returns 1. If the
cursorPosition is 3, currentSectionIndex is 0, and so on. cursorPosition is 3, currentSectionIndex is 0, and so on.
\a setCurrentSection() \sa setCurrentSection(), currentSection()
\sa currentSection()
*/ */
int QDateTimeEdit::currentSectionIndex() const int QDateTimeEdit::currentSectionIndex() const

View File

@ -1200,8 +1200,8 @@ QMargins QLineEdit::textMargins() const
The input mask is an input template string. It can contain the following elements: The input mask is an input template string. It can contain the following elements:
\table \table
\row \li Mask Characters \li Defines the class of input characters that are \row \li Mask Characters \li Defines the \l {QChar::} {Category} of input characters
considered valid in this position that are considered valid in this position
\row \li Meta Characters \li Various special meanings \row \li Meta Characters \li Various special meanings
\row \li Separators \li All other characters are regarded as immutable separators \row \li Separators \li All other characters are regarded as immutable separators
\endtable \endtable
@ -1210,17 +1210,21 @@ QMargins QLineEdit::textMargins() const
\table \table
\header \li Mask Character \li Meaning \header \li Mask Character \li Meaning
\row \li \c A \li ASCII alphabetic character required. A-Z, a-z. \row \li \c A \li character of the Letter category required, such as A-Z, a-z.
\row \li \c a \li ASCII alphabetic character permitted but not required. \row \li \c a \li character of the Letter category permitted but not required.
\row \li \c N \li ASCII alphanumeric character required. A-Z, a-z, 0-9. \row \li \c N \li character of the Letter or Number category required, such as
\row \li \c n \li ASCII alphanumeric character permitted but not required. A-Z, a-z, 0-9.
\row \li \c n \li character of the Letter or Number category permitted but not required.
\row \li \c X \li Any non-blank character required. \row \li \c X \li Any non-blank character required.
\row \li \c x \li Any non-blank character permitted but not required. \row \li \c x \li Any non-blank character permitted but not required.
\row \li \c 9 \li ASCII digit required. 0-9. \row \li \c 9 \li character of the Number category required, e.g 0-9.
\row \li \c 0 \li ASCII digit permitted but not required. \row \li \c 0 \li character of the Number category permitted but not required.
\row \li \c D \li ASCII digit required. 1-9. \row \li \c D \li character of the Number category and larger than zero required,
\row \li \c d \li ASCII digit permitted but not required (1-9). such as 1-9
\row \li \c # \li ASCII digit or plus/minus sign permitted but not required. \row \li \c d \li character of the Number category and larger than zero permitted but not
required, such as 1-9.
\row \li \c # \li character of the Number category, or plus/minus sign permitted but not
required.
\row \li \c H \li Hexadecimal character required. A-F, a-f, 0-9. \row \li \c H \li Hexadecimal character required. A-F, a-f, 0-9.
\row \li \c h \li Hexadecimal character permitted but not required. \row \li \c h \li Hexadecimal character permitted but not required.
\row \li \c B \li Binary character required. 0-1. \row \li \c B \li Binary character required. 0-1.
@ -1262,7 +1266,7 @@ QMargins QLineEdit::textMargins() const
To get range control (e.g., for an IP address) use masks together To get range control (e.g., for an IP address) use masks together
with \l{setValidator()}{validators}. with \l{setValidator()}{validators}.
\sa maxLength \sa maxLength, QChar::isLetter(), QChar::isNumber(), QChar::digitValue()
*/ */
QString QLineEdit::inputMask() const QString QLineEdit::inputMask() const
{ {

View File

@ -580,11 +580,26 @@ void tst_QDeadlineTimer::stdchrono()
auto now = QDeadlineTimer::current(timerType); auto now = QDeadlineTimer::current(timerType);
QTest::qSleep(minResolution); QTest::qSleep(minResolution);
auto sampling_start = steady_clock::now();
auto steady_deadline = now.deadline<steady_clock>();
auto system_deadline = now.deadline<system_clock>();
auto steady_after = steady_clock::now(); auto steady_after = steady_clock::now();
auto system_after = system_clock::now(); auto system_after = system_clock::now();
auto sampling_end = steady_clock::now();
auto sampling_diff = duration_cast<milliseconds>(sampling_end - sampling_start).count();
if (sampling_diff > minResolution/2) {
qWarning() << "Sampling clock took" << sampling_diff << "ms";
QSKIP("Sampling clock took too long, aborting test", Abort);
}
auto total_diff = duration_cast<milliseconds>(steady_after - steady_before).count();
if (total_diff >= 3*minResolution) {
qWarning() << "Measurement took" << total_diff << "ms";
QSKIP("Measurement took too long, aborting test", Abort);
}
{ {
auto diff = duration_cast<milliseconds>(steady_after - now.deadline<steady_clock>()); auto diff = duration_cast<milliseconds>(steady_after - steady_deadline);
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
QDeadlineTimer dt_after(steady_after, timerType); QDeadlineTimer dt_after(steady_after, timerType);
@ -592,7 +607,7 @@ void tst_QDeadlineTimer::stdchrono()
("now = " + QLocale().toString(now.deadlineNSecs()) + ("now = " + QLocale().toString(now.deadlineNSecs()) +
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1()); "; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
diff = duration_cast<milliseconds>(now.deadline<steady_clock>() - steady_before); diff = duration_cast<milliseconds>(steady_deadline - steady_before);
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
QDeadlineTimer dt_before(steady_before, timerType); QDeadlineTimer dt_before(steady_before, timerType);
@ -601,7 +616,7 @@ void tst_QDeadlineTimer::stdchrono()
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1()); "; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
} }
{ {
auto diff = duration_cast<milliseconds>(system_after - now.deadline<system_clock>()); auto diff = duration_cast<milliseconds>(system_after - system_deadline);
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
QDeadlineTimer dt_after(system_after, timerType); QDeadlineTimer dt_after(system_after, timerType);
@ -609,7 +624,7 @@ void tst_QDeadlineTimer::stdchrono()
("now = " + QLocale().toString(now.deadlineNSecs()) + ("now = " + QLocale().toString(now.deadlineNSecs()) +
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1()); "; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
diff = duration_cast<milliseconds>(now.deadline<system_clock>() - system_before); diff = duration_cast<milliseconds>(system_deadline - system_before);
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
QDeadlineTimer dt_before(system_before, timerType); QDeadlineTimer dt_before(system_before, timerType);

View File

@ -7462,6 +7462,12 @@ void tst_QObject::checkArgumentsForNarrowing()
FITS(bool, const QObject *&); FITS(bool, const QObject *&);
FITS(int (*)(bool), void (QObject::*)()); FITS(int (*)(bool), void (QObject::*)());
{
// wg21.link/P1957
NARROWS(char*, bool);
NARROWS(void (QObject::*)(), bool);
}
#undef IS_UNSCOPED_ENUM_SIGNED #undef IS_UNSCOPED_ENUM_SIGNED
#undef NARROWS_IF #undef NARROWS_IF

View File

@ -59,6 +59,7 @@ private slots:
void mnemonicTextWidth(); void mnemonicTextWidth();
void leadingBelowLine(); void leadingBelowLine();
void elidedMetrics(); void elidedMetrics();
void zeroWidthMetrics();
}; };
void tst_QFontMetrics::same() void tst_QFontMetrics::same()
@ -358,5 +359,28 @@ void tst_QFontMetrics::elidedMetrics()
QFontDatabase::removeApplicationFont(id); QFontDatabase::removeApplicationFont(id);
} }
void tst_QFontMetrics::zeroWidthMetrics()
{
QString zwnj(QChar(0x200c));
QString zwsp(QChar(0x200b));
QFont font;
QFontMetricsF fm(font);
QCOMPARE(fm.horizontalAdvance(zwnj), 0);
QCOMPARE(fm.horizontalAdvance(zwsp), 0);
QCOMPARE(fm.boundingRect(zwnj).width(), 0);
QCOMPARE(fm.boundingRect(zwsp).width(), 0);
QString string1 = QStringLiteral("(") + zwnj + QStringLiteral(")");
QString string2 = QStringLiteral("(") + zwnj + zwnj + QStringLiteral(")");
QString string3 = QStringLiteral("(") + zwsp + QStringLiteral(")");
QString string4 = QStringLiteral("(") + zwsp + zwsp + QStringLiteral(")");
QCOMPARE(fm.horizontalAdvance(string1), fm.horizontalAdvance(string2));
QCOMPARE(fm.horizontalAdvance(string3), fm.horizontalAdvance(string4));
QCOMPARE(fm.boundingRect(string1).width(), fm.boundingRect(string2).width());
QCOMPARE(fm.boundingRect(string3).width(), fm.boundingRect(string4).width());
}
QTEST_MAIN(tst_QFontMetrics) QTEST_MAIN(tst_QFontMetrics)
#include "tst_qfontmetrics.moc" #include "tst_qfontmetrics.moc"