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 <Cristian.Maureira-Fredes@qt.io>
Change-Id: I58782e7ad0e2ff9d89ed695f8a23b1e584cfed64
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
Volker Hilsheimer 2021-07-16 12:58:41 +02:00
parent 3ee587f8fa
commit a1a6e3d21b
2 changed files with 50 additions and 5 deletions

View File

@ -1599,11 +1599,21 @@ QSize Declaration::sizeValue() const
return qvariant_cast<QSize>(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<QSize>(size);

View File

@ -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<QString>("styleSheet");
QTest::addColumn<QFont>("font");
QTest::addColumn<QSize>("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"