summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc3
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp72
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp28
3 files changed, 80 insertions, 23 deletions
diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
index f4edfb92dc..44f20ca0ae 100644
--- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
@@ -3027,7 +3027,8 @@
\list
\li \c px: pixels
\li \c pt: the size of one point (i.e., 1/72 of an inch)
- \li \c em: the em width of the font (i.e., the width of 'M')
+ \li \c em: the size relative to the font size of the element
+ (e.g., 2em means 2 times the size of the font)
\li \c ex: the x-height of the font (i.e., the height of 'x')
\endlist
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index bc23dfd6ac..d5eafa2e9d 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -1051,31 +1051,59 @@ QRenderRule::QRenderRule(const QList<Declaration> &declarations, const QObject *
for (int i = 0; i < numKnownStyleHints; i++) {
QLatin1String styleHint(knownStyleHints[i]);
if (decl.d->property.compare(styleHint) == 0) {
- QString hintName = QString(styleHint);
- QVariant hintValue;
- if (hintName.endsWith(QLatin1String("alignment"))) {
- hintValue = (int) decl.alignmentValue();
- } else if (hintName.endsWith(QLatin1String("color"))) {
- hintValue = (int) decl.colorValue().rgba();
- } else if (hintName.endsWith(QLatin1String("size"))) {
- hintValue = decl.sizeValue();
- } else if (hintName.endsWith(QLatin1String("icon"))) {
- hintValue = decl.iconValue();
- } else if (hintName == QLatin1String("button-layout")
- && decl.d->values.count() != 0 && decl.d->values.at(0).type == Value::String) {
- hintValue = subControlLayout(decl.d->values.at(0).variant.toString());
- } else {
- int integer;
- decl.intValue(&integer);
- hintValue = integer;
- }
- styleHints[decl.d->property] = hintValue;
- knownStyleHint = true;
- break;
+ QString hintName = QString(styleHint);
+ QVariant hintValue;
+ if (hintName.endsWith(QLatin1String("alignment"))) {
+ hintValue = (int) decl.alignmentValue();
+ } else if (hintName.endsWith(QLatin1String("color"))) {
+ hintValue = (int) decl.colorValue().rgba();
+ } else if (hintName.endsWith(QLatin1String("size"))) {
+ // Check only for the 'em' case
+ const QString valueString = decl.d->values.at(0).variant.toString();
+ const bool isEmSize = valueString.endsWith(u"em", Qt::CaseInsensitive);
+ if (isEmSize || valueString.endsWith(u"ex", Qt::CaseInsensitive)) {
+ // 1em == size of font; 1ex == xHeight of font
+ // See lengthValueFromData helper in qcssparser.cpp
+ QFont fontForSize(font);
+ // if no font is specified, then use the widget font if possible
+ if (const QWidget *widget; !hasFont && (widget = qobject_cast<const QWidget*>(object)))
+ fontForSize = widget->font();
+
+ const QFontMetrics fontMetrics(fontForSize);
+ qreal pixelSize = isEmSize ? fontMetrics.height() : fontMetrics.xHeight();
+
+ // Transform size according to the 'em'/'ex' value
+ qreal emexSize = {};
+ if (decl.realValue(&emexSize, isEmSize ? "em" : "ex") && emexSize > 0) {
+ pixelSize *= emexSize;
+ const QSizeF newSize(pixelSize, pixelSize);
+ decl.d->parsed = QVariant::fromValue<QSizeF>(newSize);
+ hintValue = newSize;
+ } else {
+ qWarning("Invalid '%s' size for %s. Skipping.",
+ isEmSize ? "em" : "ex", qPrintable(valueString));
+ }
+ } else {
+ // Normal case where we receive a 'px' or 'pt' unit
+ hintValue = decl.sizeValue();
+ }
+ } else if (hintName.endsWith(QLatin1String("icon"))) {
+ hintValue = decl.iconValue();
+ } else if (hintName == QLatin1String("button-layout")
+ && decl.d->values.count() != 0 && decl.d->values.at(0).type == Value::String) {
+ hintValue = subControlLayout(decl.d->values.at(0).variant.toString());
+ } else {
+ int integer;
+ decl.intValue(&integer);
+ hintValue = integer;
+ }
+ styleHints[decl.d->property] = hintValue;
+ knownStyleHint = true;
+ break;
}
}
if (!knownStyleHint)
- qDebug("Unknown property %s", qPrintable(decl.d->property));
+ qWarning("Unknown property %s", qPrintable(decl.d->property));
}
}
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
index 63db23f3b0..272c175042 100644
--- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
+++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
@@ -2352,12 +2352,40 @@ void tst_QStyleSheetStyle::iconSizes_data()
smallFont.setPointSizeF(9.0);
QFont largeFont;
largeFont.setPointSizeF(24.0);
+ QFont hugeFont;
+ hugeFont.setPointSizeF(40.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);
+
+ const QFontMetrics defaultMetrics{QFont()};
+ const QFontMetrics smallMetrics(smallFont);
+ const QFontMetrics largeMetrics(largeFont);
+ const QFontMetrics hugeMetrics(hugeFont);
+ QTest::addRow("1em, default font") << "icon-size: 1em"
+ << QFont() << QSize(defaultMetrics.height(), defaultMetrics.height());
+ QTest::addRow("1em, small font") << "icon-size: 1em"
+ << smallFont << QSize(smallMetrics.height(), smallMetrics.height());
+ QTest::addRow("1em, large font") << "icon-size: 1em"
+ << largeFont << QSize(largeMetrics.height(), largeMetrics.height());
+ QTest::addRow("1.5em, lage font") << "icon-size: 1.5em"
+ << largeFont << QSize(largeMetrics.height(), largeMetrics.height()) * 1.5;
+ QTest::addRow("2em with styled font") << "font-size: 40pt; icon-size: 2em"
+ << QFont() << QSize(hugeMetrics.height(), hugeMetrics.height()) * 2;
+
+ QTest::addRow("1ex, default font") << "icon-size: 1ex"
+ << QFont() << QSize(defaultMetrics.xHeight(), defaultMetrics.xHeight());
+ QTest::addRow("1ex, small font") << "icon-size: 1ex"
+ << smallFont << QSize(smallMetrics.xHeight(), smallMetrics.xHeight());
+ QTest::addRow("1ex, large font") << "icon-size: 1ex"
+ << largeFont << QSize(largeMetrics.xHeight(), largeMetrics.xHeight());
+ QTest::addRow("1.5ex, lage font") << "icon-size: 1.5ex"
+ << largeFont << QSize(largeMetrics.xHeight(), largeMetrics.xHeight()) * 1.5;
+ QTest::addRow("2ex with styled font") << "font-size: 40pt; icon-size: 2ex"
+ << QFont() << QSize(hugeMetrics.xHeight(), hugeMetrics.xHeight()) * 2;
}
void tst_QStyleSheetStyle::iconSizes()