diff options
author | Tor Arne Vestbø <[email protected]> | 2024-08-11 23:23:40 +0200 |
---|---|---|
committer | Tor Arne Vestbø <[email protected]> | 2024-08-13 11:14:25 +0200 |
commit | 5731e3e185d3a69502b2bc4f1fee48c156b34c3c (patch) | |
tree | 4bc3daca5dec02bdc3e386500caf67d9fc68050c | |
parent | 4ed994487484b37ff960144806445f8f9ce42286 (diff) |
QTextHtmlParser: Handle fractional font-size pixel values
The CSS spec defines the font-size as being a length, which is a
combination of a real number and a unit. This applies to the 'px'
unit as well, so by treating px values as integers when parsing
we were failing to parse not only '12.5px' but also '12.0px'.
The code now uses QMetaType::fromType<qreal> but then sets the
resulting pixel type on the QFont as an integer, as QFont does
not support fractional pixel sizes.
Other code paths in the CSS parsing machinery use QString::toInt(),
either directly or via intValueHelper() or lengthValue(). The font
code path can potentially be ported over to these other APIs for
consistency, but to keep the patch simple this is left for a
follow-up.
Pick-to: 6.8 6.5 6.2 5.15
Change-Id: I972cfe0f3fa3c785efa18c7593d6a497ff28911c
Reviewed-by: Eskil Abrahamsen Blomfeldt <[email protected]>
-rw-r--r-- | src/gui/text/qcssparser.cpp | 2 | ||||
-rw-r--r-- | tests/auto/gui/text/qcssparser/tst_qcssparser.cpp | 61 |
2 files changed, 62 insertions, 1 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 7886d9ba91b..b894f539779 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -1157,7 +1157,7 @@ static bool setFontSizeFromValue(QCss::Value value, QFont *font, int *fontSizeAd } else if (s.endsWith("px"_L1, Qt::CaseInsensitive)) { s.chop(2); value.variant = s; - if (value.variant.convert(QMetaType::fromType<int>())) { + if (value.variant.convert(QMetaType::fromType<qreal>())) { font->setPixelSize(qBound(0, value.variant.toInt(), (1 << 24) - 1)); valid = true; } diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp index 2d577198840..61731313317 100644 --- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp +++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp @@ -50,6 +50,8 @@ private slots: void gradient(); void extractFontFamily_data(); void extractFontFamily(); + void extractFontSize_data(); + void extractFontSize(); void extractBorder_data(); void extractBorder(); void noTextDecoration(); @@ -1626,6 +1628,65 @@ void tst_QCssParser::extractFontFamily() QTEST(info.family(), "expectedFamily"); } +void tst_QCssParser::extractFontSize_data() +{ + QTest::addColumn<QString>("css"); + QTest::addColumn<int>("expectedPixelSize"); + QTest::addColumn<int>("expectedPointSize"); + QTest::addColumn<qreal>("expectedPointSizeF"); + + QTest::newRow("integer point size") << "font-size: 12pt" << -1 << 12 << 12.0; + QTest::newRow("float point size round down") << "font-size: 12.3pt" << -1 << 12 << 12.3; + QTest::newRow("float point size midpoint") << "font-size: 12.5pt" << -1 << 13 << 12.5; + QTest::newRow("float point size round up") << "font-size: 12.7pt" << -1 << 13 << 12.7; + + QTest::newRow("integer pixel size") << "font-size: 12px" << 12 << -1 << -1.0; + QTest::newRow("float pixel size round down") << "font-size: 12.3px" << 12 << -1 << -1.0; + QTest::newRow("float pixel size midpoint") << "font-size: 12.5px" << 13 << -1 << -1.0; + QTest::newRow("float pixel size round up") << "font-size: 12.7px" << 13 << -1 << -1.0; + + QTest::newRow("shorthand integer point size") << "font: 12pt Arial" << -1 << 12 << 12.0; + QTest::newRow("shorthand float point size round down") << "font: 12.3pt Arial" << -1 << 12 << 12.3; + QTest::newRow("shorthand float point size midpoint") << "font: 12.5pt Arial" << -1 << 13 << 12.5; + QTest::newRow("shorthand float point size round up") << "font: 12.7pt Arial" << -1 << 13 << 12.7; + + QTest::newRow("shorthand integer pixel size") << "font: 12px Arial" << 12 << -1 << -1.0; + QTest::newRow("shorthand float pixel size round down") << "font: 12.3px Arial" << 12 << -1 << -1.0; + QTest::newRow("shorthand float pixel size midpoint") << "font: 12.5px Arial" << 13 << -1 << -1.0; + QTest::newRow("shorthand float pixel size round up") << "font: 12.7px Arial" << 13 << -1 << -1.0; +} + +void tst_QCssParser::extractFontSize() +{ + QFETCH(QString, css); + css.prepend("dummy {"); + css.append(QLatin1Char('}')); + + QCss::Parser parser(css); + QCss::StyleSheet sheet; + QVERIFY(parser.parse(&sheet)); + + QCOMPARE(sheet.styleRules.size() + sheet.nameIndex.size(), 1); + QCss::StyleRule rule = (!sheet.styleRules.isEmpty()) ? + sheet.styleRules.at(0) : *sheet.nameIndex.begin(); + + const QList<QCss::Declaration> decls = rule.declarations; + QVERIFY(!decls.isEmpty()); + QCss::ValueExtractor extractor(decls); + + int adjustment = 0; + QFont font; + extractor.extractFont(&font, &adjustment); + + QFETCH(int, expectedPixelSize); + QFETCH(int, expectedPointSize); + QFETCH(qreal, expectedPointSizeF); + + QCOMPARE(font.pixelSize(), expectedPixelSize); + QCOMPARE(font.pointSize(), expectedPointSize); + QCOMPARE(font.pointSizeF(), expectedPointSizeF); +} + void tst_QCssParser::extractBorder_data() { QTest::addColumn<QString>("css"); |