diff options
Diffstat (limited to 'tests/auto/gui/text/qtextlayout')
-rw-r--r-- | tests/auto/gui/text/qtextlayout/CMakeLists.txt | 11 | ||||
-rw-r--r-- | tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 171 |
2 files changed, 132 insertions, 50 deletions
diff --git a/tests/auto/gui/text/qtextlayout/CMakeLists.txt b/tests/auto/gui/text/qtextlayout/CMakeLists.txt index 3fb5dea8b9..655c0985a0 100644 --- a/tests/auto/gui/text/qtextlayout/CMakeLists.txt +++ b/tests/auto/gui/text/qtextlayout/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qtextlayout.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qtextlayout Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qtextlayout LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + qt_internal_add_test(tst_qtextlayout SOURCES tst_qtextlayout.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Gui Qt::GuiPrivate diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index def7c88593..209f5a56e2 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses /* !!!!!! Warning !!!!! @@ -124,7 +125,9 @@ private slots: void tooManyDirectionalCharctersCrash_qtbug77819(); void softHyphens_data(); void softHyphens(); + void min_maximumWidth_data(); void min_maximumWidth(); + void negativeLineWidth(); private: QFont testFont; @@ -289,14 +292,14 @@ void tst_QTextLayout::simpleBoundingRect() QString hello("hello world"); - const int width = hello.length() * testFont.pixelSize(); + const int width = hello.size() * testFont.pixelSize(); QTextLayout layout(hello, testFont); layout.beginLayout(); QTextLine line = layout.createLine(); line.setLineWidth(width); - QCOMPARE(line.textLength(), hello.length()); + QCOMPARE(line.textLength(), hello.size()); QCOMPARE(layout.boundingRect(), QRectF(0, 0, width, QFontMetrics(testFont).height())); } @@ -331,18 +334,18 @@ void tst_QTextLayout::threeLineBoundingRect() QString thirdWord("world"); QString text(firstWord + wordBoundary1 + secondWord + wordBoundary2 + thirdWord); - int firstLineWidth = firstWord.length() * testFont.pixelSize(); - int secondLineWidth = secondWord.length() * testFont.pixelSize(); - int thirdLineWidth = thirdWord.length() * testFont.pixelSize(); + int firstLineWidth = firstWord.size() * testFont.pixelSize(); + int secondLineWidth = secondWord.size() * testFont.pixelSize(); + int thirdLineWidth = thirdWord.size() * testFont.pixelSize(); // Trailing spaces do not count to line width: if (!wordBoundary1.isSpace()) firstLineWidth += testFont.pixelSize(); if (!wordBoundary2.isSpace()) secondLineWidth += testFont.pixelSize(); // But trailing spaces do count to line length: - const int firstLineLength = firstWord.length() + 1; - const int secondLineLength = secondWord.length() + 1; - const int thirdLineLength = thirdWord.length(); + const int firstLineLength = firstWord.size() + 1; + const int secondLineLength = secondWord.size() + 1; + const int thirdLineLength = thirdWord.size(); const int longestLine = qMax(firstLineWidth, qMax(secondLineWidth, thirdLineWidth)); @@ -386,7 +389,7 @@ void tst_QTextLayout::boundingRectWithLongLineAndNoWrap() { QString longString("thisisaverylongstringthatcannotbewrappedatallitjustgoesonandonlikeonebigword"); - const int width = longString.length() * testFont.pixelSize() / 20; // very small widthx + const int width = longString.size() * testFont.pixelSize() / 20; // very small widthx QTextLayout layout(longString, testFont); layout.beginLayout(); @@ -511,18 +514,24 @@ void tst_QTextLayout::noWrap() void tst_QTextLayout::cursorToXForInlineObjects() { - QChar ch(QChar::ObjectReplacementCharacter); - QString text(ch); - QTextLayout layout(text, testFont); - layout.beginLayout(); + QString text = QStringLiteral("<html><body><img src=\"\" width=\"32\" height=\"32\" /></body></html>"); - QTextEngine *engine = layout.engine(); - const int item = engine->findItem(0); - engine->layoutData->items[item].width = 32; + QTextDocument document; + document.setHtml(text); + QCOMPARE(document.blockCount(), 1); - QTextLine line = layout.createLine(); - line.setLineWidth(0x10000); + // Trigger layout + { + QImage img(1, 1, QImage::Format_ARGB32_Premultiplied); + QPainter p(&img); + document.drawContents(&p); + } + QTextLayout *layout = document.firstBlock().layout(); + QVERIFY(layout != nullptr); + QCOMPARE(layout->lineCount(), 1); + + QTextLine line = layout->lineAt(0); QCOMPARE(line.cursorToX(0), qreal(0)); QCOMPARE(line.cursorToX(1), qreal(32)); } @@ -720,29 +729,29 @@ void tst_QTextLayout::cursorToXForBidiBoundaries_data() QTest::addColumn<Qt::LayoutDirection>("textDirection"); QTest::addColumn<QString>("text"); QTest::addColumn<int>("cursorPosition"); - QTest::addColumn<int>("expectedX"); + QTest::addColumn<int>("runsToInclude"); QTest::addRow("LTR, abcشزذabc, 0") << Qt::LeftToRight << "abcشزذabc" << 0 << 0; QTest::addRow("RTL, abcشزذabc, 9") << Qt::RightToLeft << "abcشزذabc" - << 9 << TESTFONT_SIZE * 3; + << 9 << 1; QTest::addRow("LTR, abcشزذabc, 3") << Qt::LeftToRight << "abcشزذabc" << 0 << 0; QTest::addRow("RTL, abcشزذabc, 6") << Qt::RightToLeft << "abcشزذabc" - << 9 << TESTFONT_SIZE * 3; + << 9 << 1; QTest::addRow("LTR, شزذabcشزذ, 0") << Qt::LeftToRight << "شزذabcشزذ" - << 0 << TESTFONT_SIZE * 2; + << 0 << 1; QTest::addRow("RTL, شزذabcشزذ, 9") << Qt::RightToLeft << "شزذabcشزذ" << 9 << 0; QTest::addRow("LTR, شزذabcشزذ, 3") << Qt::LeftToRight << "شزذabcشزذ" - << 3 << TESTFONT_SIZE * 2; + << 3 << 1; QTest::addRow("RTL, شزذabcشزذ, 3") << Qt::RightToLeft << "شزذabcشزذ" - << 3 << TESTFONT_SIZE * 5; + << 3 << 2; QTest::addRow("LTR, شزذabcشزذ, 6") << Qt::LeftToRight << "شزذabcشزذ" - << 6 << TESTFONT_SIZE * 5; + << 6 << 2; QTest::addRow("RTL, شزذabcشزذ, 6") << Qt::RightToLeft << "شزذabcشزذ" - << 6 << TESTFONT_SIZE * 2; + << 6 << 1; } void tst_QTextLayout::cursorToXForBidiBoundaries() @@ -750,7 +759,7 @@ void tst_QTextLayout::cursorToXForBidiBoundaries() QFETCH(Qt::LayoutDirection, textDirection); QFETCH(QString, text); QFETCH(int, cursorPosition); - QFETCH(int, expectedX); + QFETCH(int, runsToInclude); QTextOption option; option.setTextDirection(textDirection); @@ -759,12 +768,30 @@ void tst_QTextLayout::cursorToXForBidiBoundaries() layout.setTextOption(option); layout.beginLayout(); - QTextLine line = layout.createLine(); - line.setLineWidth(0x10000); + { + QTextLine line = layout.createLine(); + line.setLineWidth(0x10000); + } + layout.endLayout(); - QCOMPARE(line.cursorToX(cursorPosition), expectedX); + QTextLine line = layout.lineAt(0); + QList<QGlyphRun> glyphRuns = line.glyphRuns(-1, + -1, + QTextLayout::RetrieveStringIndexes + | QTextLayout::RetrieveGlyphIndexes); + QVERIFY(runsToInclude <= glyphRuns.size()); + + std::sort(glyphRuns.begin(), glyphRuns.end(), + [](const QGlyphRun &first, const QGlyphRun &second) { + return first.stringIndexes().first() < second.stringIndexes().first(); + }); + + qreal expectedX = 0.0; + for (int i = 0; i < runsToInclude; ++i) { + expectedX += glyphRuns.at(i).boundingRect().width(); + } - layout.endLayout(); + QCOMPARE(line.cursorToX(cursorPosition), expectedX); } void tst_QTextLayout::horizontalAlignment_data() @@ -1139,7 +1166,7 @@ void tst_QTextLayout::xToCursorAtEndOfLine() QString text = "FirstLine SecondLine"; text.replace('\n', QChar::LineSeparator); - const qreal firstLineWidth = QString("FirstLine").length() * testFont.pixelSize(); + const qreal firstLineWidth = QString("FirstLine").size() * testFont.pixelSize(); QTextLayout layout(text, testFont); layout.setCacheEnabled(true); @@ -1282,7 +1309,7 @@ void tst_QTextLayout::integerOverflow() QVERIFY(line.isValid()); line.setLineWidth(INT_MAX); - QCOMPARE(line.textLength(), txt.length()); + QCOMPARE(line.textLength(), txt.size()); QVERIFY(!layout.createLine().isValid()); @@ -1857,7 +1884,7 @@ void tst_QTextLayout::capitalization_allUpperCase() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 1); + QCOMPARE(engine->layoutData->items.size(), 1); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Uppercase)); } @@ -1877,7 +1904,7 @@ void tst_QTextLayout::capitalization_allUpperCase_newline() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 3); + QCOMPARE(engine->layoutData->items.size(), 3); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Uppercase)); QCOMPARE(engine->layoutData->items.at(1).analysis.flags, ushort(QScriptAnalysis::LineOrParagraphSeparator)); QCOMPARE(engine->layoutData->items.at(2).analysis.flags, ushort(QScriptAnalysis::Uppercase)); @@ -1895,7 +1922,7 @@ void tst_QTextLayout::capitalization_allLowerCase() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 1); + QCOMPARE(engine->layoutData->items.size(), 1); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Lowercase)); } @@ -1911,7 +1938,7 @@ void tst_QTextLayout::capitalization_smallCaps() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 2); + QCOMPARE(engine->layoutData->items.size(), 2); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::None)); QCOMPARE(engine->layoutData->items.at(1).analysis.flags, ushort(QScriptAnalysis::SmallCaps)); } @@ -1928,7 +1955,7 @@ void tst_QTextLayout::capitalization_capitalize() QTextEngine *engine = layout.engine(); engine->itemize(); - QCOMPARE(engine->layoutData->items.count(), 5); + QCOMPARE(engine->layoutData->items.size(), 5); QCOMPARE(engine->layoutData->items.at(0).analysis.flags, ushort(QScriptAnalysis::Uppercase)); QCOMPARE(engine->layoutData->items.at(1).analysis.flags, ushort(QScriptAnalysis::None)); QCOMPARE(engine->layoutData->items.at(2).analysis.flags, ushort(QScriptAnalysis::Tab)); @@ -2039,7 +2066,7 @@ void tst_QTextLayout::columnWrapWithTabs() textLayout.beginLayout(); QTextLine line = textLayout.createLine(); line.setNumColumns(30); - QCOMPARE(line.textLength(), text.length()); + QCOMPARE(line.textLength(), text.size()); textLayout.endLayout(); } @@ -2050,7 +2077,7 @@ void tst_QTextLayout::columnWrapWithTabs() textLayout.beginLayout(); QTextLine line = textLayout.createLine(); line.setNumColumns(30); - QVERIFY(line.textLength() < text.length()); + QVERIFY(line.textLength() < text.size()); textLayout.endLayout(); } @@ -2454,7 +2481,7 @@ void tst_QTextLayout::nbspWithFormat() layout.setText(s1 + s2 + nbsp + s3); QTextLayout::FormatRange formatRange; - formatRange.start = s1.length() + s2.length(); + formatRange.start = s1.size() + s2.size(); formatRange.length = 1; formatRange.format.setFontUnderline(true); @@ -2471,9 +2498,9 @@ void tst_QTextLayout::nbspWithFormat() QCOMPARE(layout.lineCount(), 2); QCOMPARE(layout.lineAt(0).textStart(), 0); - QCOMPARE(layout.lineAt(0).textLength(), s1.length()); - QCOMPARE(layout.lineAt(1).textStart(), s1.length()); - QCOMPARE(layout.lineAt(1).textLength(), s2.length() + 1 + s3.length()); + QCOMPARE(layout.lineAt(0).textLength(), s1.size()); + QCOMPARE(layout.lineAt(1).textStart(), s1.size()); + QCOMPARE(layout.lineAt(1).textLength(), s2.size() + 1 + s3.size()); } void tst_QTextLayout::koreanWordWrap() @@ -2647,13 +2674,35 @@ void tst_QTextLayout::softHyphens() } } +void tst_QTextLayout::min_maximumWidth_data() +{ + QTest::addColumn<QString>("text"); + + QTest::newRow("long string") << QStringLiteral("lmong_long_crazy_87235982735_23857239682376923876923876-fuwhfhfw-names-AAAA-deeaois2019-03-03.and.more"); + QTest::newRow("QTBUG-106947") << QStringLiteral("text text"); + QTest::newRow("spaces") << QStringLiteral(" text text "); + QTest::newRow("QTBUG-104986") << QStringLiteral("text\ntext\ntext"); + QTest::newRow("spaces + line breaks") << QStringLiteral(" \n text\n \ntext \n "); +} + void tst_QTextLayout::min_maximumWidth() { - QString longString("lmong_long_crazy_87235982735_23857239682376923876923876-fuwhfhfw-names-AAAA-deeaois2019-03-03.and.more"); - QTextLayout layout(longString, testFont); + QFETCH(QString, text); + text.replace('\n', QChar::LineSeparator); + + QTextLayout layout(text, testFont); + layout.setCacheEnabled(true); + + QTextOption opt; + opt.setWrapMode(QTextOption::NoWrap); + layout.setTextOption(opt); + layout.beginLayout(); + while (layout.createLine().isValid()) { } + layout.endLayout(); + + const qreal nonWrappedMaxWidth = layout.maximumWidth(); for (int wrapMode = QTextOption::NoWrap; wrapMode <= QTextOption::WrapAtWordBoundaryOrAnywhere; ++wrapMode) { - QTextOption opt; opt.setWrapMode((QTextOption::WrapMode)wrapMode); layout.setTextOption(opt); layout.beginLayout(); @@ -2662,6 +2711,9 @@ void tst_QTextLayout::min_maximumWidth() const qreal minWidth = layout.minimumWidth(); const qreal maxWidth = layout.maximumWidth(); + QCOMPARE_LE(minWidth, maxWidth); + QCOMPARE_LE(maxWidth, nonWrappedMaxWidth); // maxWidth for wrapped text shouldn't exceed maxWidth for the text without wrapping. + // Try the layout from slightly wider than the widest (maxWidth) // and narrow it down to slighly narrower than minWidth // layout.maximumWidth() should return the same regardless @@ -2683,5 +2735,28 @@ void tst_QTextLayout::min_maximumWidth() } } +void tst_QTextLayout::negativeLineWidth() +{ + { + QTextLayout layout; + layout.setText("Foo bar"); + layout.beginLayout(); + QTextLine line = layout.createLine(); + line.setLineWidth(-1); + QVERIFY(line.textLength() > 0); + layout.endLayout(); + } + + { + QTextLayout layout; + layout.setText("Foo bar"); + layout.beginLayout(); + QTextLine line = layout.createLine(); + line.setNumColumns(2, -1); + QVERIFY(line.textLength() > 0); + layout.endLayout(); + } +} + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" |