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>
This commit is contained in:
Allan Sandfeld Jensen 2018-11-26 11:22:07 +01:00
parent 76ee79b8b9
commit e823c351c6
5 changed files with 44 additions and 8 deletions

View File

@ -247,6 +247,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
#ifndef QT_NO_TOOLTIP
, toolTipDuration(-1)
#endif
, directFontResolveMask(0)
, inheritedFontResolveMask(0)
, inheritedPaletteResolveMask(0)
, leftmargin(0)
@ -4751,6 +4752,18 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
return naturalFont;
}
/*!
\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
@ -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));

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);