diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-11-26 11:22:07 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-01-22 18:43:18 +0000 |
commit | e823c351c6226765ccfe66e2ee93a2797dcc9721 (patch) | |
tree | 8af9ead9b84269c2c935ef524f768d66d3f184bb | |
parent | 76ee79b8b9c412a77bb51f127ab102f2451a7bbb (diff) |
Fix resolve() on fonts returned from QWidget::font()
Set the inherited properties as resolved on the font, so non-default
values are passed on in contexts that does resolve logic like QPainter.
One test is updated as it actually tests what it is supposed to on
more configurations.
Fixes: QTBUG-39560
Change-Id: Ief668e992ccdc091337a259a4c1306a00e67c73f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 20 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 4 | ||||
-rw-r--r-- | src/widgets/styles/qstylesheetstyle.cpp | 11 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 13 | ||||
-rw-r--r-- | tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp | 4 |
5 files changed, 44 insertions, 8 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 9f7c486148..6227996ff8 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -247,6 +247,7 @@ QWidgetPrivate::QWidgetPrivate(int version) #ifndef QT_NO_TOOLTIP , toolTipDuration(-1) #endif + , directFontResolveMask(0) , inheritedFontResolveMask(0) , inheritedPaletteResolveMask(0) , leftmargin(0) @@ -4754,6 +4755,18 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const /*! \internal + Returns a font suitable for inheritance, where only locally set attributes are considered resolved. +*/ +QFont QWidgetPrivate::localFont() const +{ + QFont localfont = data.fnt; + localfont.resolve(directFontResolveMask); + return localfont; +} + +/*! + \internal + Determine which font is implicitly imposed on this widget by its ancestors and QApplication::font, resolve this against its own font (attributes from the implicit font are copied over). Then propagate this font to this @@ -4762,7 +4775,7 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const void QWidgetPrivate::resolveFont() { QFont naturalFont = naturalWidgetFont(inheritedFontResolveMask); - QFont resolvedFont = data.fnt.resolve(naturalFont); + QFont resolvedFont = localFont().resolve(naturalFont); setFont_helper(resolvedFont); } @@ -4801,6 +4814,11 @@ void QWidgetPrivate::updateFont(const QFont &font) inheritedFontResolveMask = 0; } uint newMask = data.fnt.resolve() | inheritedFontResolveMask; + // Set the font as also having resolved inherited traits, so the result of reading QWidget::font() + // isn't all weak information, but save the original mask to be able to let new changes on the + // parent widget font propagate correctly. + directFontResolveMask = data.fnt.resolve(); + data.fnt.resolve(newMask); for (int i = 0; i < children.size(); ++i) { QWidget *w = qobject_cast<QWidget*>(children.at(i)); diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 6f1ce67c4c..0d7e9e26ba 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -383,10 +383,11 @@ public: void updateFont(const QFont &); inline void setFont_helper(const QFont &font) { - if (data.fnt.resolve() == font.resolve() && data.fnt == font) + if (directFontResolveMask == font.resolve() && data.fnt == font) return; updateFont(font); } + QFont localFont() const; void resolveFont(); QFont naturalWidgetFont(uint inheritedMask) const; @@ -729,6 +730,7 @@ public: #endif // Other variables. + uint directFontResolveMask; uint inheritedFontResolveMask; uint inheritedPaletteResolveMask; short leftmargin; diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 96c6fdf2e2..7c1c0ca3d8 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -2642,7 +2642,7 @@ void QStyleSheetStyle::setPalette(QWidget *w) QRenderRule rule = renderRule(w, PseudoElement_None, map[i].state | extendedPseudoClass(w)); if (i == 0) { if (!w->property("_q_styleSheetWidgetFont").isValid()) { - saveWidgetFont(w, w->font()); + saveWidgetFont(w, w->d_func()->localFont()); } updateStyleSheetFont(w); if (ew != w) @@ -6025,7 +6025,7 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const unsetStyleSheetFont(w); if (rule.font.resolve()) { - QFont wf = w->font(); + QFont wf = w->d_func()->localFont(); styleSheetCaches->customFontWidgets.insert(w, {wf, rule.font.resolve()}); QFont font = rule.font.resolve(wf); @@ -6033,7 +6033,9 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const w->setFont(font); } } else { - QFont font = rule.font.resolve(w->font()); + QFont wf = w->d_func()->localFont(); + QFont font = rule.font.resolve(wf); + font.resolve(wf.resolve() | rule.font.resolve()); if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation)) && isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) { @@ -6041,10 +6043,11 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const font = font.resolve(static_cast<QWidget *>(w->parent())->font()); } - if (w->data->fnt == font) + if (wf.resolve() == font.resolve() && wf == font) return; w->data->fnt = font; + w->d_func()->directFontResolveMask = font.resolve(); QEvent e(QEvent::FontChange); QApplication::sendEvent(w, &e); diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 360e6986f6..3b9c9060fa 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -166,6 +166,7 @@ private slots: void getSetCheck(); void fontPropagation(); void fontPropagation2(); + void fontPropagation3(); void palettePropagation(); void palettePropagation2(); void enabledPropagation(); @@ -819,6 +820,18 @@ void tst_QWidget::fontPropagation2() QVERIFY(child5->font().italic()); } +void tst_QWidget::fontPropagation3() +{ + QWidget parent; + QWidget *child = new QWidget(&parent); + parent.setFont(QFont("Monospace", 9)); + QImage image(32, 32, QImage::Format_RGB32); + QPainter p(&image); + p.setFont(child->font()); + QCOMPARE(p.font().family(), child->font().family()); + QCOMPARE(p.font().pointSize(), child->font().pointSize()); +} + void tst_QWidget::palettePropagation() { QScopedPointer<QWidget> testWidget(new QWidget); diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 03f24ba151..0e5c40f1b6 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -741,9 +741,9 @@ void tst_QStyleSheetStyle::fontPropagation() QCOMPARE(FONTSIZE(pb), 20); QWidget window; - window.setStyleSheet("* { font-size: 10pt }"); + window.setStyleSheet("* { font-size: 9pt }"); pb.setParent(&window); - QCOMPARE(FONTSIZE(pb), 10); + QCOMPARE(FONTSIZE(pb), 9); window.setStyleSheet(""); QCOMPARE(FONTSIZE(pb), buttonFontSize); |