From a1a6e3d21b1a4fb799dfd245fed6bb6564178894 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 16 Jul 2021 12:58:41 +0200 Subject: [PATCH] Support pt units for sizes, as documented Declaration::lengthValue only supported 'px' sizes, but one can transform any 'pt' value into 'px' by multiplying with 1.33. Notes: this ignores display DPI, and instead follows the W3C definition of 'pt' and 'px' as absolute lengths [1]. [1] https://www.w3.org/TR/css3-values/#absolute-lengths 1pt = 1/72th of 1 inch 1px = 1/96th of 1 inch so the conversion is px = pt * (72/96). Add unit test that verifies this using QPushButton's icon-sizes property, also with changed font in preparation of adding support for 'em' and 'ex' units in a follow up commit. Task-number: QTBUG-8096 Pick-to: 6.2 Done-with: Cristian Maureira-Fredes Change-Id: I58782e7ad0e2ff9d89ed695f8a23b1e584cfed64 Reviewed-by: Andy Shaw --- src/gui/text/qcssparser.cpp | 20 ++++++++--- .../qstylesheetstyle/tst_qstylesheetstyle.cpp | 35 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 4cc310c7e72..62e14e92bb9 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -1599,11 +1599,21 @@ QSize Declaration::sizeValue() const return qvariant_cast(d->parsed); int x[2] = { 0, 0 }; - if (d->values.count() > 0) - intValueHelper(d->values.at(0), &x[0], "px"); - if (d->values.count() > 1) - intValueHelper(d->values.at(1), &x[1], "px"); - else + const int count = d->values.count(); + for (int i = 0; i < count; ++i) { + const auto &value = d->values.at(i); + const QString valueString = value.variant.toString(); + if (valueString.endsWith(u"pt", Qt::CaseInsensitive)) { + intValueHelper(value, &x[i], "pt"); + // according to https://www.w3.org/TR/css3-values/#absolute-lengths + // 1pt = 1/72th of 1 inch, and 1px = 1/96th of 1 inch + x[i] *= 72.0/96.0; + } else { + // by default we use 'px' + intValueHelper(value, &x[i], "px"); + } + } + if (count == 1) x[1] = x[0]; QSize size(x[0], x[1]); d->parsed = QVariant::fromValue(size); diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index a4ce5ac77ed..63db23f3b02 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -139,6 +139,9 @@ private slots: void highdpiImages_data(); void highdpiImages(); + void iconSizes_data(); + void iconSizes(); + private: static QColor COLOR(const QWidget &w) { @@ -2337,6 +2340,38 @@ void tst_QStyleSheetStyle::placeholderColor() QCOMPARE(le2.palette().placeholderText(), red); } +void tst_QStyleSheetStyle::iconSizes_data() +{ + QTest::addColumn("styleSheet"); + QTest::addColumn("font"); + QTest::addColumn("iconSize"); + + const int defaultSize = QApplication::style()->pixelMetric(QStyle::PM_ButtonIconSize); + + QFont smallFont; + smallFont.setPointSizeF(9.0); + QFont largeFont; + largeFont.setPointSizeF(24.0); + + QTest::addRow("default") << QString() << QFont() << QSize(defaultSize, defaultSize); + QTest::addRow("pixels") << "icon-size: 50px" << QFont() << QSize(50, 50); + QTest::addRow("points") << "icon-size: 20pt" << QFont() << QSize(15, 15); + QTest::addRow("pixels with font") << "icon-size: 50px" << smallFont << QSize(50, 50); + QTest::addRow("points with font") << "icon-size: 20pt" << largeFont << QSize(15, 15); +} + +void tst_QStyleSheetStyle::iconSizes() +{ + QFETCH(QString, styleSheet); + QFETCH(QFont, font); + QFETCH(QSize, iconSize); + + QPushButton button; + button.setFont(font); + button.setStyleSheet(styleSheet); + QCOMPARE(button.iconSize(), iconSize); +} + QTEST_MAIN(tst_QStyleSheetStyle) #include "tst_qstylesheetstyle.moc"