summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-11-26 11:22:07 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-01-22 18:43:18 +0000
commite823c351c6226765ccfe66e2ee93a2797dcc9721 (patch)
tree8af9ead9b84269c2c935ef524f768d66d3f184bb
parent76ee79b8b9c412a77bb51f127ab102f2451a7bbb (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.cpp20
-rw-r--r--src/widgets/kernel/qwidget_p.h4
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp11
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp13
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp4
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);