diff options
Diffstat (limited to 'tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp')
-rw-r--r-- | tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp | 378 |
1 files changed, 366 insertions, 12 deletions
diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp index 1569a4bf84..8c0c0324c9 100644 --- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp +++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp @@ -1,5 +1,5 @@ // 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 #include <QTest> @@ -39,6 +39,10 @@ private slots: void mixedScripts(); void multiLineBoundingRect(); void defaultIgnorables(); + void stringIndexes(); + void retrievalFlags_data(); + void retrievalFlags(); + void objectReplacementCharacter(); private: int m_testFontId; @@ -404,7 +408,7 @@ void tst_QGlyphRun::drawMultiScriptText1() QPixmap drawGlyphs(1000, 1000); drawGlyphs.fill(Qt::white); - QList<QGlyphRun> glyphsList = textLayout.glyphRuns(); + const QList<QGlyphRun> glyphsList = textLayout.glyphRuns(); QCOMPARE(glyphsList.size(), 1); { @@ -414,8 +418,7 @@ void tst_QGlyphRun::drawMultiScriptText1() { QPainter p(&drawGlyphs); - foreach (QGlyphRun glyphs, glyphsList) - p.drawGlyphRun(QPointF(50, 50), glyphs); + p.drawGlyphRun(QPointF(50, 50), glyphsList.first()); } #if defined(DEBUG_SAVE_IMAGE) @@ -445,7 +448,7 @@ void tst_QGlyphRun::drawMultiScriptText2() QPixmap drawGlyphs(1000, 1000); drawGlyphs.fill(Qt::white); - QList<QGlyphRun> glyphsList = textLayout.glyphRuns(); + const QList<QGlyphRun> glyphsList = textLayout.glyphRuns(); QCOMPARE(glyphsList.size(), 2); { @@ -455,7 +458,7 @@ void tst_QGlyphRun::drawMultiScriptText2() { QPainter p(&drawGlyphs); - foreach (QGlyphRun glyphs, glyphsList) + for (const QGlyphRun &glyphs : glyphsList) p.drawGlyphRun(QPointF(50, 50), glyphs); } @@ -560,6 +563,9 @@ void tst_QGlyphRun::boundingRect() void tst_QGlyphRun::mixedScripts() { + if (QFontDatabase::families(QFontDatabase::Korean).isEmpty()) + QSKIP("This test requires support for Hangul text"); + QString s; s += QChar(0x31); // The character '1' s += QChar(0xbc14); // Hangul character @@ -605,17 +611,365 @@ void tst_QGlyphRun::multiLineBoundingRect() void tst_QGlyphRun::defaultIgnorables() { + { + QTextLayout layout; + layout.setFont(QFont("QtsSpecialTestFont")); + layout.setText(QChar(0x200D)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> runs = layout.glyphRuns(); + QCOMPARE(runs.size(), 0); + } + + { + QTextLayout layout; + layout.setFont(QFont("QtsSpecialTestFont")); + layout.setText(QStringLiteral("AAA") + QChar(0xFE0F) + QStringLiteral("111")); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> runs = layout.glyphRuns(); + QVERIFY(!runs.isEmpty()); + + bool hasFullMainFontRun = false; + for (const QGlyphRun &run : runs) { + // QtsSpecialFont will be used for at least five characters: AA[...]111 + // Depending on the font selected for the 0xFE0F variant selector, the + // third 'A' may be in QtsSpecialFont or in the fallback. This is platform-specific, + // so we accept either. + if (run.rawFont().familyName() == QStringLiteral("QtsSpecialTestFont") + && run.glyphIndexes().size() >= 5) { + hasFullMainFontRun = true; + break; + } + } + QVERIFY(hasFullMainFontRun); + } +} + +void tst_QGlyphRun::stringIndexes() +{ + int ligatureFontId = QFontDatabase::addApplicationFont(QFINDTESTDATA("Ligatures.otf")); + QVERIFY(ligatureFontId >= 0); + + QFont ligatureFont = QFont("QtLigatures"); + QCOMPARE(QFontInfo(ligatureFont).family(), QString::fromLatin1("QtLigatures")); + + QTextLayout::GlyphRunRetrievalFlags retrievalFlags + = QTextLayout::RetrieveGlyphIndexes | QTextLayout::RetrieveStringIndexes; + + // Three characters -> three glyphs + { + QTextLayout layout; + layout.setText("f i"); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 3); + QCOMPARE(stringIndexes.at(0), 0); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 2); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(2, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), 2); + } + } + + // Two characters -> one glyph + { + QTextLayout layout; + layout.setText("fi"); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), 0); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), 1); + } + } + + // Four characters -> three glyphs + { + QTextLayout layout; + layout.setText("ffii"); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 3); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(71)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(233)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 3); + QCOMPARE(stringIndexes.at(0), uint(0)); + QCOMPARE(stringIndexes.at(1), uint(1)); + QCOMPARE(stringIndexes.at(2), uint(3)); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, 1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), uint(1)); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, 2, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 1); + QCOMPARE(stringIndexes.at(0), uint(1)); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, 3, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 2); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(233)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 2); + QCOMPARE(stringIndexes.at(0), 1); + QCOMPARE(stringIndexes.at(1), 3); + } + + } + + // One character -> two glyphs + { + QTextLayout layout; + layout.setText(QChar(0xe6)); // LATIN SMALL LETTER AE + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 2); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(70)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 2); + QCOMPARE(stringIndexes.at(0), uint(0)); + QCOMPARE(stringIndexes.at(1), uint(0)); + } + + // Three characters -> four glyphs + { + QTextLayout layout; + layout.setText(QString('f') + QChar(0xe6) + QChar('i')); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 4); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(71)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(70)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(3), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 4); + QCOMPARE(stringIndexes.at(0), 0); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 1); + QCOMPARE(stringIndexes.at(3), 2); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 3); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(70)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 3); + QCOMPARE(stringIndexes.at(0), 1); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 2); + } + + { + QList<QGlyphRun> glyphRuns = layout.glyphRuns(0, 2, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 3); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(71)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(70)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 3); + QCOMPARE(stringIndexes.at(0), 0); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 1); + } + + + } + + // Five characters -> five glyphs + { + QTextLayout layout; + layout.setText(QLatin1String("ffi") + QChar(0xe6) + QLatin1Char('i')); + layout.setFont(ligatureFont); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, retrievalFlags); + QCOMPARE(glyphRuns.size(), 1); + + QCOMPARE(glyphRuns.at(0).glyphIndexes().size(), 5); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(0), uint(71)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(1), uint(233)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(2), uint(66)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(3), uint(70)); + QCOMPARE(glyphRuns.at(0).glyphIndexes().at(4), uint(74)); + + QList<qsizetype> stringIndexes = glyphRuns.at(0).stringIndexes(); + QCOMPARE(stringIndexes.size(), 5); + QCOMPARE(stringIndexes.at(0), 0); + QCOMPARE(stringIndexes.at(1), 1); + QCOMPARE(stringIndexes.at(2), 3); + QCOMPARE(stringIndexes.at(3), 3); + QCOMPARE(stringIndexes.at(4), 4); + } + +} + +void tst_QGlyphRun::retrievalFlags_data() +{ + QTest::addColumn<QTextLayout::GlyphRunRetrievalFlags>("flags"); + QTest::addColumn<bool>("expectedGlyphIndexes"); + QTest::addColumn<bool>("expectedStringIndexes"); + QTest::addColumn<bool>("expectedString"); + QTest::addColumn<bool>("expectedGlyphPositions"); + + QTest::newRow("Glyph indexes") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveGlyphIndexes) + << true << false << false << false; + QTest::newRow("Glyph Positions") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveGlyphPositions) + << false << false << false << true; + QTest::newRow("String indexes") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveStringIndexes) + << false << true << false << false; + QTest::newRow("String") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveString) + << false << false << true << false; + + QTest::newRow("Default") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::DefaultRetrievalFlags) + << true << false << false << true; + QTest::newRow("All") + << QTextLayout::GlyphRunRetrievalFlags(QTextLayout::RetrieveAll) + << true << true << true << true; +} + +void tst_QGlyphRun::retrievalFlags() +{ + QFETCH(QTextLayout::GlyphRunRetrievalFlags, flags); + QFETCH(bool, expectedGlyphIndexes); + QFETCH(bool, expectedStringIndexes); + QFETCH(bool, expectedString); + QFETCH(bool, expectedGlyphPositions); + QTextLayout layout; - layout.setFont(QFont("QtsSpecialTestFont")); - layout.setText(QChar(0x200D)); + layout.setText(QLatin1String("abc")); layout.beginLayout(); layout.createLine(); layout.endLayout(); - QList<QGlyphRun> runs = layout.glyphRuns(); - QCOMPARE(runs.size(), 1); - QCOMPARE(runs.at(0).glyphIndexes().size(), 1); - QCOMPARE(runs.at(0).glyphIndexes()[0], uint(0)); + QList<QGlyphRun> glyphRuns = layout.glyphRuns(-1, -1, flags); + QVERIFY(!glyphRuns.isEmpty()); + + QGlyphRun firstGlyphRun = glyphRuns.first(); + QCOMPARE(firstGlyphRun.glyphIndexes().isEmpty(), !expectedGlyphIndexes); + QCOMPARE(firstGlyphRun.stringIndexes().isEmpty(), !expectedStringIndexes); + QCOMPARE(firstGlyphRun.sourceString().isEmpty(), !expectedString); + QCOMPARE(firstGlyphRun.positions().isEmpty(), !expectedGlyphPositions); +} + +void tst_QGlyphRun::objectReplacementCharacter() +{ + QTextLayout layout; + layout.setFont(m_testFont); + layout.setText(QStringLiteral("\uFFFC")); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 1); + QCOMPARE(glyphRuns.first().glyphIndexes().size(), 1); + QCOMPARE(glyphRuns.first().glyphIndexes().first(), uint(5)); } #endif // QT_NO_RAWFONT |