diff options
Diffstat (limited to 'tests/auto/gui/text/qfontdatabase')
-rw-r--r-- | tests/auto/gui/text/qfontdatabase/CMakeLists.txt | 14 | ||||
-rw-r--r-- | tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf | bin | 0 -> 5664 bytes | |||
-rw-r--r-- | tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf | bin | 0 -> 5280 bytes | |||
-rw-r--r-- | tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp | 283 |
4 files changed, 281 insertions, 16 deletions
diff --git a/tests/auto/gui/text/qfontdatabase/CMakeLists.txt b/tests/auto/gui/text/qfontdatabase/CMakeLists.txt index a1c93f8ff7..0cb6e8d7c8 100644 --- a/tests/auto/gui/text/qfontdatabase/CMakeLists.txt +++ b/tests/auto/gui/text/qfontdatabase/CMakeLists.txt @@ -1,12 +1,16 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -# Generated from qfontdatabase.pro. - ##################################################################### ## tst_qfontdatabase Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qfontdatabase LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + # Collect test data list(APPEND test_data "LED_REAL.TTF") @@ -33,12 +37,18 @@ set_source_files_properties("../../../shared/resources/testfont_italic.ttf" set_source_files_properties("../../../shared/resources/testfont_open.otf" PROPERTIES QT_RESOURCE_ALIAS "testfont_open.otf" ) +set_source_files_properties("../../../shared/resources/testfont_variable.ttf" + PROPERTIES QT_RESOURCE_ALIAS "testfont_variable.ttf" +) set(testdata_resource_files "../../../shared/resources/testfont.ttf" "../../../shared/resources/testfont_condensed.ttf" "../../../shared/resources/testfont_italic.ttf" "../../../shared/resources/testfont_open.otf" + "../../../shared/resources/testfont_variable.ttf" "LED_REAL.TTF" + "QtTestLimitedFont-Regular.ttf" + "QtTestFallbackFont-Regular.ttf" ) qt_internal_add_resource(tst_qfontdatabase "testdata" diff --git a/tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf b/tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf Binary files differnew file mode 100644 index 0000000000..ae21fec9a5 --- /dev/null +++ b/tests/auto/gui/text/qfontdatabase/QtTestFallbackFont-Regular.ttf diff --git a/tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf b/tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf Binary files differnew file mode 100644 index 0000000000..2891f8aeff --- /dev/null +++ b/tests/auto/gui/text/qfontdatabase/QtTestLimitedFont-Regular.ttf diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp index 9c56d9b2d2..8733f64d97 100644 --- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp +++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.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> #include <QSignalSpy> @@ -12,6 +12,9 @@ #include <private/qfont_p.h> #include <private/qfontengine_p.h> #include <qpa/qplatformfontdatabase.h> +#include <qpa/qplatformintegration.h> + +#include <QtGui/private/qguiapplication_p.h> using namespace Qt::StringLiterals; @@ -61,15 +64,22 @@ private slots: void stretchRespected(); + void variableFont(); + #ifdef Q_OS_WIN void findCourier(); #endif + void addApplicationFontFallback(); + private: QString m_ledFont; QString m_testFont; QString m_testFontCondensed; QString m_testFontItalic; + QString m_testFontVariable; + QString m_limitedFont; + QString m_fallbackFont; }; tst_QFontDatabase::tst_QFontDatabase() @@ -82,10 +92,16 @@ void tst_QFontDatabase::initTestCase() m_testFont = QFINDTESTDATA("testfont.ttf"); m_testFontCondensed = QFINDTESTDATA("testfont_condensed.ttf"); m_testFontItalic = QFINDTESTDATA("testfont_italic.ttf"); + m_testFontVariable = QFINDTESTDATA("testfont_variable.ttf"); + m_limitedFont = QFINDTESTDATA("QtTestLimitedFont-Regular.ttf"); + m_fallbackFont = QFINDTESTDATA("QtTestFallbackFont-Regular.ttf"); QVERIFY(!m_ledFont.isEmpty()); QVERIFY(!m_testFont.isEmpty()); QVERIFY(!m_testFontCondensed.isEmpty()); QVERIFY(!m_testFontItalic.isEmpty()); + QVERIFY(!m_testFontVariable.isEmpty()); + QVERIFY(!m_limitedFont.isEmpty()); + QVERIFY(!m_fallbackFont.isEmpty()); } void tst_QFontDatabase::styles_data() @@ -223,7 +239,7 @@ void tst_QFontDatabase::addAppFont() int id; if (useMemoryFont) { QFile fontfile(m_ledFont); - fontfile.open(QIODevice::ReadOnly); + QVERIFY(fontfile.open(QIODevice::ReadOnly)); QByteArray fontdata = fontfile.readAll(); QVERIFY(!fontdata.isEmpty()); id = QFontDatabase::addApplicationFontFromData(fontdata); @@ -236,7 +252,7 @@ void tst_QFontDatabase::addAppFont() QCOMPARE(id, -1); return; #endif - QCOMPARE(fontDbChangedSpy.count(), 1); + QCOMPARE(fontDbChangedSpy.size(), 1); if (id == -1) QSKIP("Skip the test since app fonts are not supported on this system"); @@ -245,9 +261,9 @@ void tst_QFontDatabase::addAppFont() const QStringList newFamilies = QFontDatabase::families(); QVERIFY(!newFamilies.isEmpty()); - QVERIFY(newFamilies.count() >= oldFamilies.count()); + QVERIFY(newFamilies.size() >= oldFamilies.size()); - for (int i = 0; i < addedFamilies.count(); ++i) { + for (int i = 0; i < addedFamilies.size(); ++i) { QString family = addedFamilies.at(i); QVERIFY(newFamilies.contains(family)); QFont qfont(family); @@ -256,9 +272,9 @@ void tst_QFontDatabase::addAppFont() } QVERIFY(QFontDatabase::removeApplicationFont(id)); - QCOMPARE(fontDbChangedSpy.count(), 2); + QCOMPARE(fontDbChangedSpy.size(), 2); - QVERIFY(QFontDatabase::families().count() <= oldFamilies.count()); + QVERIFY(QFontDatabase::families().size() <= oldFamilies.size()); } void tst_QFontDatabase::addTwoAppFontsFromFamily() @@ -319,8 +335,8 @@ void tst_QFontDatabase::fallbackFonts() layout.createLine(); layout.endLayout(); - QList<QGlyphRun> runs = layout.glyphRuns(0, 1); - foreach (QGlyphRun run, runs) { + const QList<QGlyphRun> runs = layout.glyphRuns(0, 1); + for (QGlyphRun run : runs) { QRawFont rawFont = run.rawFont(); QVERIFY(rawFont.isValid()); @@ -381,8 +397,14 @@ void tst_QFontDatabase::condensedFontWidthNoFontMerging() void tst_QFontDatabase::condensedFontWidth() { - QFontDatabase::addApplicationFont(m_testFont); - QFontDatabase::addApplicationFont(m_testFontCondensed); + int testFontId = QFontDatabase::addApplicationFont(m_testFont); + int testFontCondensedId = QFontDatabase::addApplicationFont(m_testFontCondensed); + auto cleanup = qScopeGuard([&testFontId, &testFontCondensedId] { + if (testFontId >= 0) + QFontDatabase::removeApplicationFont(testFontId); + if (testFontCondensedId >= 0) + QFontDatabase::removeApplicationFont(testFontCondensedId); + }); QVERIFY(QFontDatabase::hasFamily("QtBidiTestFont")); if (!QFontDatabase::hasFamily("QtBidiTestFontCondensed")) @@ -400,10 +422,16 @@ void tst_QFontDatabase::condensedFontWidth() void tst_QFontDatabase::condensedFontMatching() { QFontDatabase::removeAllApplicationFonts(); - QFontDatabase::addApplicationFont(m_testFontCondensed); + int testFontCondensedId = QFontDatabase::addApplicationFont(m_testFontCondensed); if (!QFontDatabase::hasFamily("QtBidiTestFont")) QSKIP("This platform doesn't support preferred font family names (QTBUG-53478)"); - QFontDatabase::addApplicationFont(m_testFont); + int testFontId = QFontDatabase::addApplicationFont(m_testFont); + auto cleanup = qScopeGuard([&testFontId, &testFontCondensedId] { + if (testFontId >= 0) + QFontDatabase::removeApplicationFont(testFontId); + if (testFontCondensedId >= 0) + QFontDatabase::removeApplicationFont(testFontCondensedId); + }); // Test we correctly get the condensed font using different font matching methods: QFont tfcByStretch("QtBidiTestFont"); @@ -415,8 +443,10 @@ void tst_QFontDatabase::condensedFontMatching() QFont f; f.setStyleStrategy(QFont::NoFontMerging); QFontPrivate *font_d = QFontPrivate::get(f); - if (font_d->engineForScript(QChar::Script_Common)->type() != QFontEngine::Freetype) + if (font_d->engineForScript(QChar::Script_Common)->type() != QFontEngine::Freetype + && font_d->engineForScript(QChar::Script_Common)->type() != QFontEngine::DirectWrite) { QEXPECT_FAIL("","No matching of sub-family by stretch on Windows", Continue); + } #endif QCOMPARE(QFontMetrics(tfcByStretch).horizontalAdvance(testString()), @@ -505,5 +535,230 @@ void tst_QFontDatabase::findCourier() } #endif +void tst_QFontDatabase::variableFont() +{ + { + QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); + if (!pfdb->supportsVariableApplicationFonts()) + QSKIP("Variable application fonts not supported on this platform"); + } + + int id = QFontDatabase::addApplicationFont(m_testFontVariable); + if (id == -1) + QSKIP("Skip the test since app fonts are not supported on this system"); + + QString family = QFontDatabase::applicationFontFamilies(id).first(); + { + QFont font(family); + QCOMPARE(QFontInfo(font).styleName(), u"Regular"_s); + QCOMPARE(QFontInfo(font).weight(), QFont::Normal); + } + + { + QFont font(family); + font.setWeight(QFont::Black); + QCOMPARE(QFontInfo(font).styleName(), u"QtExtraBold"_s); + QCOMPARE(QFontInfo(font).weight(), int(QFont::Black)); + } + + { + QFont regularFont(family); + QFont extraBoldFont(family); + extraBoldFont.setStyleName(u"QtExtraBold"_s); + + QFontMetricsF regularFm(regularFont); + QFontMetricsF extraBoldFm(extraBoldFont); + + QVERIFY(regularFm.horizontalAdvance(QLatin1Char('1')) < extraBoldFm.horizontalAdvance(QLatin1Char('1'))); + } + + QFontDatabase::removeApplicationFont(id); +} + +void tst_QFontDatabase::addApplicationFontFallback() +{ + int ledId = -1; + int id = -1; + int limitedId = -1; + int fallbackId = -1; + auto cleanup = qScopeGuard([&id, &ledId, &limitedId, &fallbackId] { + if (id >= 0) + QFontDatabase::removeApplicationFont(id); + if (ledId >= 0) + QFontDatabase::removeApplicationFont(ledId); + if (limitedId >= 0) + QFontDatabase::removeApplicationFont(limitedId); + if (fallbackId >= 0) + QFontDatabase::removeApplicationFont(fallbackId); + }); + + const QChar hebrewChar(0x05D0); // Hebrew 'aleph' + + ledId = QFontDatabase::addApplicationFont(m_ledFont); + if (ledId < 0) + QSKIP("Skip the test since app fonts are not supported on this system"); + + auto getHebrewFont = [&]() { + QTextLayout layout; + layout.setText(hebrewChar); + layout.setFont(QFont(u"LED Real"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + if (glyphRuns.isEmpty()) + return QString{}; + + return glyphRuns.first().rawFont().familyName(); + }; + + QString defaultHebrewFont = getHebrewFont(); + if (defaultHebrewFont.isEmpty()) + QSKIP("Skip the test since Hebrew is not supported on this system"); + + QVERIFY(QFontDatabase::applicationFallbackFontFamilies(QChar::Script_Hebrew).isEmpty()); + QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Hebrew, u"QtBidiTestFont"_s); + + QCOMPARE(QFontDatabase::applicationFallbackFontFamilies(QChar::Script_Hebrew).size(), 1); + QCOMPARE(QFontDatabase::applicationFallbackFontFamilies(QChar::Script_Hebrew).first(), u"QtBidiTestFont"_s); + + { + QString hebrewFontNow = getHebrewFont(); + QCOMPARE(hebrewFontNow, defaultHebrewFont); + } + + id = QFontDatabase::addApplicationFont(m_testFont); + QVERIFY(id >= 0); + + { + QString hebrewFontNow = getHebrewFont(); + QCOMPARE(hebrewFontNow, u"QtBidiTestFont"_s); + } + + QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Hebrew, u"QtBidiTestFont"_s); + + { + QString hebrewFontNow = getHebrewFont(); + QCOMPARE(hebrewFontNow, defaultHebrewFont); + } + + QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script_Hebrew, QStringList(u"QtBidiTestFont"_s)); + + { + QString hebrewFontNow = getHebrewFont(); + QCOMPARE(hebrewFontNow, u"QtBidiTestFont"_s); + } + + QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script_Hebrew, QStringList{}); + + { + QString hebrewFontNow = getHebrewFont(); + QCOMPARE(hebrewFontNow, defaultHebrewFont); + } + + limitedId = QFontDatabase::addApplicationFont(m_limitedFont); + QVERIFY(limitedId >= 0); + + fallbackId = QFontDatabase::addApplicationFont(m_fallbackFont); + QVERIFY(fallbackId >= 0); + + QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Common, u"QtTestFallbackFont"_s); + + // The fallback for Common will be used also for Latin, because Latin and Common are + // considered the same script by the font matching engine. + { + QTextLayout layout; + layout.setText(u"A'B,"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QVERIFY(glyphRuns.size() > 1); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s + || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s); + } + } + + // When the text only consists of common script characters, the fallback font will also be used. + { + QTextLayout layout; + layout.setText(u"',"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 2); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s + || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s); + } + } + + QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Common, u"QtTestFallbackFont"_s)); + QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Latin, u"QtTestFallbackFont"_s); + + // Latin fallback works just the same as Common fallback + { + QTextLayout layout; + layout.setText(u"A'B,"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 2); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s + || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s); + } + } + + // When the common character is placed next to a Cyrillic characters, it gets adapted to this, + // so the fallback font will not be selected, even if it supports the character in question + { + QTextLayout layout; + layout.setText(u"A'Б,"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 2); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() != u"QtTestFallbackFont"_s); + } + } + + QFontDatabase::addApplicationFallbackFontFamily(QChar::Script_Cyrillic, u"QtTestFallbackFont"_s); + + // When we set the fallback font for Cyrillic as well, it gets selected + { + QTextLayout layout; + layout.setText(u"A'Б,"_s); + layout.setFont(QFont(u"QtTestLimitedFont"_s)); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 2); + for (int i = 0; i < glyphRuns.size(); ++i) { + QVERIFY(glyphRuns.at(i).rawFont().familyName() == u"QtTestFallbackFont"_s + || glyphRuns.at(i).rawFont().familyName() == u"QtTestLimitedFont"_s); + } + } + + QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Cyrillic, u"QtTestFallbackFont"_s)); + QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Latin, u"QtTestFallbackFont"_s)); +} + QTEST_MAIN(tst_QFontDatabase) #include "tst_qfontdatabase.moc" |