From 8f37b55b6ad26e5330bfcf0ffb93668d65f3879c Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Sat, 21 Dec 2019 19:44:19 +0000 Subject: [PATCH] add QFontMetrics test Signed-off-by: Ivailo Monev --- tests/auto/qfontmetrics/CMakeLists.txt | 4 + tests/auto/qfontmetrics/testfont.qrc | 5 + tests/auto/qfontmetrics/tst_qfontmetrics.cpp | 304 +++++++++++++++++++++++++++ tests/auto/qfontmetrics/ucs4font.ttf | Bin 0 -> 3076 bytes 4 files changed, 313 insertions(+) create mode 100644 tests/auto/qfontmetrics/CMakeLists.txt create mode 100644 tests/auto/qfontmetrics/testfont.qrc create mode 100644 tests/auto/qfontmetrics/tst_qfontmetrics.cpp create mode 100644 tests/auto/qfontmetrics/ucs4font.ttf diff --git a/tests/auto/qfontmetrics/CMakeLists.txt b/tests/auto/qfontmetrics/CMakeLists.txt new file mode 100644 index 000000000..7776bae5c --- /dev/null +++ b/tests/auto/qfontmetrics/CMakeLists.txt @@ -0,0 +1,4 @@ +katie_gui_test(tst_qfontmetrics + ${CMAKE_CURRENT_SOURCE_DIR}/tst_qfontmetrics.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/testfont.qrc +) diff --git a/tests/auto/qfontmetrics/testfont.qrc b/tests/auto/qfontmetrics/testfont.qrc new file mode 100644 index 000000000..bc0c0b095 --- /dev/null +++ b/tests/auto/qfontmetrics/testfont.qrc @@ -0,0 +1,5 @@ + + + ucs4font.ttf + + diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp new file mode 100644 index 000000000..d00ee1851 --- /dev/null +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -0,0 +1,304 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016-2019 Ivailo Monev +** +** This file is part of the test suite of the Katie Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include +#include +#include +#include +#include + + + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QFontMetrics : public QObject +{ +Q_OBJECT + +public: + tst_QFontMetrics(); + virtual ~tst_QFontMetrics(); + +public slots: + void init(); + void cleanup(); +private slots: + void same(); + void metrics(); + void boundingRect(); + void elidedText_data(); + void elidedText(); + void veryNarrowElidedText(); + void averageCharWidth(); + void bypassShaping(); + void elidedMultiLength(); + void elidedMultiLengthF(); + void inFontUcs4(); + void lineWidth(); +}; + +tst_QFontMetrics::tst_QFontMetrics() + +{ +} + +tst_QFontMetrics::~tst_QFontMetrics() +{ + +} + +void tst_QFontMetrics::init() +{ +} + +void tst_QFontMetrics::cleanup() +{ +} + +void tst_QFontMetrics::same() +{ + QFont font; + font.setBold(true); + QFontMetrics fm(font); + const QString text = QLatin1String("Some stupid STRING"); + QCOMPARE(fm.size(0, text), fm.size(0, text)) ; + + { + QImage image; + QFontMetrics fm2(font, &image); + QString text2 = QLatin1String("Foo Foo"); + QCOMPARE(fm2.size(0, text2), fm2.size(0, text2)); //used to crash + } + + { + QImage image; + QFontMetricsF fm3(font, &image); + QString text2 = QLatin1String("Foo Foo"); + QCOMPARE(fm3.size(0, text2), fm3.size(0, text2)); //used to crash + } +} + + +void tst_QFontMetrics::metrics() +{ + QFont font; + QFontDatabase fdb; + + // Query the QFontDatabase for a specific font, store the + // result in family, style and size. + QStringList families = fdb.families(); + if (families.isEmpty()) + return; + + QStringList::ConstIterator f_it, f_end = families.end(); + for (f_it = families.begin(); f_it != f_end; ++f_it) { + const QString &family = *f_it; + + QStringList styles = fdb.styles(family); + QStringList::ConstIterator s_it, s_end = styles.end(); + for (s_it = styles.begin(); s_it != s_end; ++s_it) { + const QString &style = *s_it; + + if (fdb.isSmoothlyScalable(family, style)) { + // smoothly scalable font... don't need to load every pointsize + font = fdb.font(family, style, 12); + + QFontMetrics fontmetrics(font); + QCOMPARE(fontmetrics.ascent() + fontmetrics.descent() + 1, + fontmetrics.height()); + + QCOMPARE(fontmetrics.height() + fontmetrics.leading(), + fontmetrics.lineSpacing()); + } else { + QList sizes = fdb.pointSizes(family, style); + QVERIFY(!sizes.isEmpty()); + QList::ConstIterator z_it, z_end = sizes.end(); + for (z_it = sizes.begin(); z_it != z_end; ++z_it) { + const int size = *z_it; + + // Initialize the font, and check if it is an exact match + font = fdb.font(family, style, size); + + QFontMetrics fontmetrics(font); + QCOMPARE(fontmetrics.ascent() + fontmetrics.descent() + 1, + fontmetrics.height()); + QCOMPARE(fontmetrics.height() + fontmetrics.leading(), + fontmetrics.lineSpacing()); + } + } + } + } +} + +void tst_QFontMetrics::boundingRect() +{ + QFont f; + f.setPointSize(24); + QFontMetrics fm(f); + QRect r = fm.boundingRect(QChar('Y')); + QVERIFY(r.top() < 0); + r = fm.boundingRect(QString("Y")); + QVERIFY(r.top() < 0); +} + +void tst_QFontMetrics::elidedText_data() +{ + QTest::addColumn("font"); + QTest::addColumn("text"); + + QTest::newRow("helvetica hello") << QFont("helvetica",10) << QString("hello") ; + QTest::newRow("helvetica hello &Bye") << QFont("helvetica",10) << QString("hello&Bye") ; +} + + +void tst_QFontMetrics::elidedText() +{ + QFETCH(QFont, font); + QFETCH(QString, text); + QFontMetrics fm(font); + int w = fm.width(text); + QString newtext = fm.elidedText(text,Qt::ElideRight,w+1, 0); + QCOMPARE(text,newtext); // should not elide + newtext = fm.elidedText(text,Qt::ElideRight,w-1, 0); + QVERIFY(text != newtext); // should elide +} + +void tst_QFontMetrics::veryNarrowElidedText() +{ + QFont f; + QFontMetrics fm(f); + QString text("hello"); + QCOMPARE(fm.elidedText(text, Qt::ElideRight, 0), QString()); +} + +void tst_QFontMetrics::averageCharWidth() +{ + QFont f; + QFontMetrics fm(f); + QVERIFY(fm.averageCharWidth() != 0); + QFontMetricsF fmf(f); + QVERIFY(fmf.averageCharWidth() != 0); +} + +void tst_QFontMetrics::bypassShaping() +{ + QFont f; + f.setStyleStrategy(QFont::ForceIntegerMetrics); + QFontMetrics fm(f); + QString text = " A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z"; + int textWidth = fm.width(text, -1, Qt::TextBypassShaping); + QVERIFY(textWidth != 0); + int charsWidth = 0; + for (int i = 0; i < text.size(); ++i) + charsWidth += fm.width(text[i]); + // This assertion is needed in QtWebKit's WebCore::Font::offsetForPositionForSimpleText + QCOMPARE(textWidth, charsWidth); +} + +template void elidedMultiLength_helper() +{ + QString text1 = QString::fromLatin1("Long Text 1\x9cShorter\x9csmall"); + QString text1_long = "Long Text 1"; + QString text1_short = "Shorter"; + QString text1_small = "small"; + FontMetrics fm = FontMetrics(QFont()); + int width_long = fm.size(0, text1_long).width(); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, 8000), text1_long); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long + 1), text1_long); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long - 1), text1_short); + int width_short = fm.size(0, text1_short).width(); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short + 1), text1_short); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short - 1), text1_small); + + // Not even wide enough for "small" - should use ellipsis + QChar ellipsisChar(0x2026); + QString text1_el = QString::fromLatin1("s") + ellipsisChar; + int width_small = fm.width(text1_el); + QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_small + 1), text1_el); +} + +void tst_QFontMetrics::elidedMultiLength() +{ + elidedMultiLength_helper(); +} + +void tst_QFontMetrics::elidedMultiLengthF() +{ + elidedMultiLength_helper(); +} + +void tst_QFontMetrics::inFontUcs4() +{ + int id = QFontDatabase::addApplicationFont(":/fonts/ucs4font.ttf"); + QVERIFY(id >= 0); + + QFont font("QtTestUcs4"); + { + QFontMetrics fm(font); + + QVERIFY(fm.inFontUcs4(0x1D7FF)); + } + + { + QFontMetricsF fm(font); + + QVERIFY(fm.inFontUcs4(0x1D7FF)); + } + + QFontDatabase::removeApplicationFont(id); +} + +void tst_QFontMetrics::lineWidth() +{ + // QTBUG-13009, QTBUG-13011 + QFont smallFont; + smallFont.setPointSize(8); + smallFont.setWeight(QFont::Light); + const QFontMetrics smallFontMetrics(smallFont); + + QFont bigFont; + bigFont.setPointSize(40); + bigFont.setWeight(QFont::Black); + const QFontMetrics bigFontMetrics(bigFont); + + QVERIFY(smallFontMetrics.lineWidth() >= 1); + QVERIFY(smallFontMetrics.lineWidth() < bigFontMetrics.lineWidth()); +} + +QTEST_MAIN(tst_QFontMetrics) + +#include "moc_tst_qfontmetrics.cpp" +#include "qrc_testfont.cpp" diff --git a/tests/auto/qfontmetrics/ucs4font.ttf b/tests/auto/qfontmetrics/ucs4font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..31b69977790334ffe71ace734112efe5081beef0 GIT binary patch literal 3076 zcma);3wYIK9mhZCf3~wLyRZ?=1LGWa3CG4RZc2bSU|Y}x2b*$^kubNzHeqtw2C+f{ zMWvG(S(c(%X4%Cq2g^DV5#8;gR)$)MS($02Sz^(J*7yDGNIgFKJpIpeKJWLv|K8v4 z{lD)YA5bJ@!1+DhD}3kUf$s&C1}^BXZ@O~T&b`X-Q-0$`ZL1=i&lrs=e-bjE>>KWl z({OMIvKOm`ToIJZ~u!+o(rgLzVc@esvwZ*J)nG>@|A>ciSf~6m%4cuc+SkhxDRPrS zV7PZj+$;25r}{zVLznjs$DVlb#3QPA^Vi0=j*d;FXo9?_Tzz~b7FWeQ)z>PYf%Ap_ z$BsOmxuJ0JOO*NDJlwzQ;d>_2V|z4v%sb*af8;n%*`q$*^Aob$zf|>Cc}HxdbfqPp zm3YiZ_i;06TJ@7(O#8h9zWrp9;T`r8D!Fbl^&OYJ|F9OXf%y2yD6Ot?(gw55)*+nm z4yz*MRN6W#KphBXGv(HKx+tdtL-%2=)O z;Po00<{Hl=C|#pbU0fY&H8#{yF3vaBGh4dBd4)z}ljec5G!HZzTQr+?pz$0kr59*U zc!O~v)zXVJGb}cqtNGDhJX1W+*eWYvsoPyFGcK1c&?Z};-Pj?E;EmLaD~u~;7re>X zDeLr7y8X&3<7(Lm7sy8FGOnRTdaW#lZetI6-?&ir!bQe)vKk^R6r;wAWjnmtxLzxO zw{Wg_iE)FyQyaAo=rvwy`>Ri@(OYVaX-%++<>G*GP%DEWtqd+RZl*(ei*Z=1gv+%` z*lLWkQu?i0D~uRN>69MRieZ~^yVebFW3{-$IIh*h+qHUlhjAxsq^~gUk|*Gu@&xQQ z?x9EeO8En>GVYaE;A(e@aEtKkKu0PXNXIGR-T5>89y(7LlSrH95mh|ufrFN zUzG3RUbc&0GJaVRfRrKt_Zbf{F8vk70S+6#s%XFwc8Xs!9#u@>>+BN0Vf>~d1K(0) z;M>OUut)m4#`_f|_@1H!-#7k%z0yBatl$CTgNhhD#I@p&j6YV~;3tY3JZ$_a3F%{s z9z0@vR566dj6dUg>7Of-@C)PPiYFXrzxaglmx?Mp$&KQ#jK5ZF;WvscJZ1bXH%ULO z2*dA;&nV9Dtnv5UEd2*X8~$i~PBDk)xmEm=@dZU5{;bHuUyLtuyYvagA6_#4Rl5NG z#vS5GpkcJ1-}Ylb;*NosyT8 zSD2rjUo<6qN^wC>K}lh5;k2oFQ)iUsmjE zuWqU-t2w(aShuioR^##oa~5=-SMAP+4E_E3_uKuZJ6buP@(oIJm9Efzk}s1ctTe+; zZEx}pRN2erYN2PQ(e9;3)n0$6U!zY-Cwpg#oUX`0pYMif$~SR!indwz>7Md$xTG$n z>pm1}A8JebHY(%Qs-Pw;<*yBOB>hz#Ya)H{_3vCnn-eYTQJ$$ z77d2Oq4wm_u1NA|TQD4rs#V~$rLy>np&4nLvt)CiM)lc~qjX1-t-&PGM8b{P9jOQ> zcPA3Tgw~PHr#SkG0w1p|XiXQ$6Bpp~=gHqiDasz_kbNV$3ZL$G|Gb9Al5laj zq_o^St7(bX(mda*m{Z`b^9D}ck|=NKm^-(lrTpd8+jr`?udr%q(e?zZLUe{fb@YiV?D9au?zb~o7ct$wr%MhX`J8C(6GpTiY@wY-K#0xQ)9Z5Vmf!n zbRYF8ZPu+7)5*V0r+Kf==0<%LG}v#E&hBxQjOwO-wSNC^nR`R^Ox$Z<5tEt!;eP