Widget style: Use per-screen DPI in QStyleHelper::dpiScaled()

Pass the style option to dpiScaled() in order to get
the correct screen DPI. The style option contains the
font, which again contains the current DPI value.

Add QFontMetrics::fontDpi() accessors to get the DPI
from the QFont. This DPI will/should be updated on screen
change.

Replace hardcoded Q_OS_MAC DPI with hardcoded base
DPI. This makes per-screen DPI testable on macOS, too.

Task-number: QTBUG-45055
Change-Id: I75f8b37d45eb50c3334b46b8469a546d29712f1b
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Friedemann Kleint 2019-04-04 13:53:19 +02:00 committed by Morten Johan Sørvig
parent f1e40dd6d6
commit d603ee689f
13 changed files with 213 additions and 140 deletions

View File

@ -1036,8 +1036,15 @@ int QFontMetrics::lineWidth() const
return qRound(engine->lineThickness());
}
/*!
\since 5.14
Returns the font DPI.
*/
qreal QFontMetrics::fontDpi() const
{
return d->dpi;
}
/*****************************************************************************
QFontMetricsF member functions
@ -1913,4 +1920,14 @@ qreal QFontMetricsF::lineWidth() const
return engine->lineThickness().toReal();
}
/*!
\since 5.14
Returns the font DPI.
*/
qreal QFontMetricsF::fontDpi() const
{
return d->dpi;
}
QT_END_NAMESPACE

View File

@ -135,6 +135,8 @@ public:
int strikeOutPos() const;
int lineWidth() const;
qreal fontDpi() const;
bool operator==(const QFontMetrics &other) const;
inline bool operator !=(const QFontMetrics &other) const { return !operator==(other); }
@ -216,6 +218,8 @@ public:
qreal strikeOutPos() const;
qreal lineWidth() const;
qreal fontDpi() const;
bool operator==(const QFontMetricsF &other) const;
inline bool operator !=(const QFontMetricsF &other) const { return !operator==(other); }

View File

@ -2294,11 +2294,11 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
}
break;
case PM_SmallIconSize:
ret = int(QStyleHelper::dpiScaled(16.));
ret = int(QStyleHelper::dpiScaled(16., opt));
break;
case PM_LargeIconSize:
ret = int(QStyleHelper::dpiScaled(32.));
ret = int(QStyleHelper::dpiScaled(32., opt));
break;
case PM_IconViewIconSize:

View File

@ -987,7 +987,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme,
TP_DROPDOWNBUTTON);
if (theme.isValid()) {
const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1);
const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1, option);
if (!size.isEmpty()) {
mbiw = qRound(size.width());
mbih = qRound(size.height());
@ -2145,7 +2145,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt
const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height();
const int margin = cb->frame ? 3 : 0;
const int bmarg = cb->frame ? 2 : 0;
const int arrowWidth = qRound(QStyleHelper::dpiScaled(16));
const int arrowWidth = qRound(QStyleHelper::dpiScaled(16, option));
const int arrowButtonWidth = bmarg + arrowWidth;
const int xpos = x + wi - arrowButtonWidth;
@ -2179,7 +2179,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt
const int height = tb->rect.height();
const int width = tb->rect.width();
const int buttonWidth =
qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor - QStyleHelper::dpiScaled(4));
qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor - QStyleHelper::dpiScaled(4, option));
const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
@ -2280,7 +2280,7 @@ int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *opti
int ret = QWindowsVistaStylePrivate::fixedPixelMetric(metric);
if (ret != QWindowsStylePrivate::InvalidMetric)
return int(QStyleHelper::dpiScaled(ret));
return int(QStyleHelper::dpiScaled(ret, option));
return QWindowsXPStyle::pixelMetric(metric, option, widget);
}

View File

@ -1486,8 +1486,9 @@ case PE_Frame:
// Inner white border
p->setPen(QPen(option->palette.base().color(), 0));
const auto topLevelAdjustment = QStyleHelper::dpiScaled(0.5);
const auto bottomRightAdjustment = QStyleHelper::dpiScaled(-1);
const qreal dpi = QStyleHelper::dpi(option);
const auto topLevelAdjustment = QStyleHelper::dpiScaled(0.5, dpi);
const auto bottomRightAdjustment = QStyleHelper::dpiScaled(-1, dpi);
p->drawRect(QRectF(option->rect).adjusted(topLevelAdjustment, topLevelAdjustment,
bottomRightAdjustment, bottomRightAdjustment));
// Outer dark border
@ -3313,7 +3314,8 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
break;
case PM_SplitterWidth:
res = qMax(int(QStyleHelper::dpiScaled(5.)), QApplication::globalStrut().width());
res = qMax(int(QStyleHelper::dpiScaled(5., option)),
QApplication::globalStrut().width());
break;
case PM_MdiSubWindowMinimizedWidth:
@ -3322,13 +3324,13 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
#if QT_CONFIG(toolbar)
case PM_ToolBarHandleExtent:
res = int(QStyleHelper::dpiScaled(8.));
res = int(QStyleHelper::dpiScaled(8., option));
break;
#endif // QT_CONFIG(toolbar)
case PM_DockWidgetSeparatorExtent:
case PM_DockWidgetTitleMargin:
res = int(QStyleHelper::dpiScaled(4.));
res = int(QStyleHelper::dpiScaled(4., option));
break;
case PM_ButtonShiftHorizontal:
@ -3413,7 +3415,7 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl
const bool isToolTitle = false;
const int height = tb->rect.height();
const int width = tb->rect.width();
const int buttonMargin = int(QStyleHelper::dpiScaled(4));
const int buttonMargin = int(QStyleHelper::dpiScaled(4, option));
const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget);
int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) * factor)
- buttonMargin;
@ -3524,23 +3526,27 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl
case CC_ComboBox:
if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
const int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
const int xpos = x + wi - qRound(QStyleHelper::dpiScaled(1 + 16));
const int xpos = x + wi - qRound(QStyleHelper::dpiScaled(1 + 16, option));
switch (subControl) {
case SC_ComboBoxFrame:
rect = cmb->rect;
break;
case SC_ComboBoxArrow:
rect = QRect(xpos, y + qRound(QStyleHelper::dpiScaled(1)),
qRound(QStyleHelper::dpiScaled(16)), he - qRound(QStyleHelper::dpiScaled(2)));
case SC_ComboBoxArrow: {
const qreal dpi = QStyleHelper::dpi(option);
rect = QRect(xpos, y + qRound(QStyleHelper::dpiScaled(1, dpi)),
qRound(QStyleHelper::dpiScaled(16, dpi)),
he - qRound(QStyleHelper::dpiScaled(2, dpi)));
}
break;
case SC_ComboBoxEditField: {
const int frame = qRound(QStyleHelper::dpiScaled(2));
const qreal dpi = QStyleHelper::dpi(option);
const int frame = qRound(QStyleHelper::dpiScaled(2, dpi));
rect = QRect(x + frame, y + frame,
wi - qRound(QStyleHelper::dpiScaled(3 + 16)),
he - qRound(QStyleHelper::dpiScaled(4)));
wi - qRound(QStyleHelper::dpiScaled(3 + 16, dpi)),
he - qRound(QStyleHelper::dpiScaled(4, dpi)));
}
break;

View File

@ -1336,7 +1336,7 @@ void QWizardPrivate::updateMinMaxSizes(const QWizardLayoutInfo &info)
int extraHeight = 0;
#if QT_CONFIG(style_windowsvista)
if (isVistaThemeEnabled())
extraHeight = vistaHelper->titleBarSize() + vistaHelper->topOffset();
extraHeight = vistaHelper->titleBarSize() + vistaHelper->topOffset(q);
#endif
QSize minimumSize = mainLayout->totalMinimumSize() + QSize(0, extraHeight);
QSize maximumSize = mainLayout->totalMaximumSize();
@ -1595,8 +1595,8 @@ bool QWizardPrivate::handleAeroStyleChange()
bool vistaMargins = false;
if (isVistaThemeEnabled()) {
const int topOffset = vistaHelper->topOffset();
const int topPadding = vistaHelper->topPadding();
const int topOffset = vistaHelper->topOffset(q);
const int topPadding = vistaHelper->topPadding(q);
if (isVistaThemeEnabled(QVistaHelper::VistaAero)) {
if (isWindow) {
vistaHelper->setDWMTitleBar(QVistaHelper::ExtendedTitleBar);
@ -3214,7 +3214,7 @@ void QWizard::resizeEvent(QResizeEvent *event)
int heightOffset = 0;
#if QT_CONFIG(style_windowsvista)
if (d->isVistaThemeEnabled()) {
heightOffset = d->vistaHelper->topOffset();
heightOffset = d->vistaHelper->topOffset(this);
if (d->isVistaThemeEnabled(QVistaHelper::VistaAero))
heightOffset += d->vistaHelper->titleBarSize();
}
@ -3246,7 +3246,7 @@ void QWizard::paintEvent(QPaintEvent * event)
if (d->isVistaThemeEnabled(QVistaHelper::VistaBasic)) {
QPainter painter(this);
QColor color = d->vistaHelper->basicWindowFrameColor();
painter.fillRect(0, 0, width(), QVistaHelper::topOffset(), color);
painter.fillRect(0, 0, width(), QVistaHelper::topOffset(this), color);
}
d->vistaHelper->paintEvent(event);
}

View File

@ -87,7 +87,7 @@ QVistaBackButton::QVistaBackButton(QWidget *widget)
QSize QVistaBackButton::sizeHint() const
{
ensurePolished();
int size = int(QStyleHelper::dpiScaled(32));
int size = int(QStyleHelper::dpiScaled(32, this));
int width = size, height = size;
return QSize(width, height);
}
@ -156,7 +156,7 @@ QVistaHelper::QVistaHelper(QWizard *wizard)
backButton_ = new QVistaBackButton(wizard);
backButton_->hide();
iconSpacing = QStyleHelper::dpiScaled(7);
iconSpacing = QStyleHelper::dpiScaled(7, wizard);
}
QVistaHelper::~QVistaHelper()
@ -229,7 +229,7 @@ bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type)
if (type == NormalTitleBar)
mar.cyTopHeight = 0;
else
mar.cyTopHeight = (titleBarSize() + topOffset()) * QVistaHelper::m_devicePixelRatio;
mar.cyTopHeight = (titleBarSize() + topOffset(wizard)) * QVistaHelper::m_devicePixelRatio;
if (const HWND wizardHandle = wizardHWND())
if (SUCCEEDED(DwmExtendFrameIntoClientArea(wizardHandle, &mar)))
value = true;
@ -275,7 +275,7 @@ void QVistaHelper::drawTitleBar(QPainter *painter)
if (vistaState() == VistaAero && isWindow)
drawBlackRect(QRect(0, 0, wizard->width(),
titleBarSize() + topOffset()), hdc);
titleBarSize() + topOffset(wizard)), hdc);
// The button is positioned in QWizardPrivate::handleAeroStyleChange(),
// all calculation is relative to it.
const int btnTop = backButton_->mapToParent(QPoint()).y();
@ -293,7 +293,7 @@ void QVistaHelper::drawTitleBar(QPainter *painter)
int glowOffset = 0;
if (vistaState() == VistaAero) {
glowOffset = glowSize();
glowOffset = glowSize(wizard);
textHeight += 2 * glowOffset;
textWidth += 2 * glowOffset;
}
@ -314,10 +314,10 @@ void QVistaHelper::drawTitleBar(QPainter *painter)
const QIcon windowIcon = wizard->windowIcon();
if (!windowIcon.isNull()) {
const int size = QVistaHelper::iconSize();
const int size = QVistaHelper::iconSize(wizard);
const int iconLeft = (wizard->layoutDirection() == Qt::LeftToRight
? leftMargin()
: wizard->width() - leftMargin() - size);
? leftMargin(wizard)
: wizard->width() - leftMargin(wizard) - size);
const QPoint pos(origin.x() + iconLeft, origin.y() + verticalCenter - size / 2);
const QPoint posDp = pos * QVistaHelper::m_devicePixelRatio;
@ -427,7 +427,7 @@ void QVistaHelper::resizeEvent(QResizeEvent * event)
{
Q_UNUSED(event);
rtTop = QRect (0, 0, wizard->width(), frameSize());
int height = captionSize() + topOffset();
int height = captionSize() + topOffset(wizard);
if (vistaState() == VistaBasic)
height -= titleBarSize();
rtTitle = QRect (0, frameSize(), wizard->width(), height);
@ -637,7 +637,7 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q
RECT rctext ={0,0, rectDp.width(), rectDp.height()};
dto.dwFlags = DTT_COMPOSITED|DTT_GLOWSIZE;
dto.iGlowSize = glowSize();
dto.iGlowSize = glowSize(wizard);
DrawThemeTextEx(hTheme, dcMem, 0, 0, reinterpret_cast<LPCWSTR>(text.utf16()), -1, uFormat, &rctext, &dto );
BitBlt(hdc, rectDp.left(), rectDp.top(), rectDp.width(), rectDp.height(), dcMem, 0, 0, SRCCOPY);
@ -714,27 +714,27 @@ int QVistaHelper::captionSizeDp()
int QVistaHelper::titleOffset()
{
int iconOffset = wizard ->windowIcon().isNull() ? 0 : iconSize() + iconSpacing;
return leftMargin() + iconOffset;
int iconOffset = wizard ->windowIcon().isNull() ? 0 : iconSize(wizard) + iconSpacing;
return leftMargin(wizard) + iconOffset;
}
int QVistaHelper::iconSize()
int QVistaHelper::iconSize(const QPaintDevice *device)
{
return QStyleHelper::dpiScaled(16); // Standard Aero
return QStyleHelper::dpiScaled(16, device); // Standard Aero
}
int QVistaHelper::glowSize()
int QVistaHelper::glowSize(const QPaintDevice *device)
{
return QStyleHelper::dpiScaled(10);
return QStyleHelper::dpiScaled(10, device);
}
int QVistaHelper::topOffset()
int QVistaHelper::topOffset(const QPaintDevice *device)
{
if (vistaState() != VistaAero)
return titleBarSize() + 3;
static const int aeroOffset =
QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8 ?
QStyleHelper::dpiScaled(4) : QStyleHelper::dpiScaled(13);
QStyleHelper::dpiScaled(4, device) : QStyleHelper::dpiScaled(13, device);
return aeroOffset + titleBarSize();
}

View File

@ -108,10 +108,10 @@ public:
static VistaState vistaState();
static int titleBarSize() { return QVistaHelper::titleBarSizeDp() / QVistaHelper::m_devicePixelRatio; }
static int titleBarSizeDp() { return QVistaHelper::frameSizeDp() + QVistaHelper::captionSizeDp(); }
static int topPadding() { // padding under text
return int(QStyleHelper::dpiScaled(4));
static int topPadding(const QPaintDevice *device) { // padding under text
return int(QStyleHelper::dpiScaled(4, device));
}
static int topOffset();
static int topOffset(const QPaintDevice *device);
static HDC backingStoreDC(const QWidget *wizard, QPoint *offset);
@ -125,10 +125,12 @@ private:
static int captionSize() { return QVistaHelper::captionSizeDp() / QVistaHelper::m_devicePixelRatio; }
static int captionSizeDp();
static int backButtonSize() { return int(QStyleHelper::dpiScaled(30)); }
static int iconSize();
static int glowSize();
int leftMargin() { return backButton_->isVisible() ? backButtonSize() + iconSpacing : 0; }
static int backButtonSize(const QPaintDevice *device)
{ return int(QStyleHelper::dpiScaled(30, device)); }
static int iconSize(const QPaintDevice *device);
static int glowSize(const QPaintDevice *device);
int leftMargin(const QPaintDevice *device)
{ return backButton_->isVisible() ? backButtonSize(device) + iconSpacing : 0; }
int titleOffset();
void drawTitleBar(QPainter *painter);

View File

@ -4247,10 +4247,11 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex
#if QT_CONFIG(combobox)
case CC_ComboBox:
if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
const qreal dpi = QStyleHelper::dpi(opt);
const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height();
const int margin = cb->frame ? qRound(QStyleHelper::dpiScaled(3)) : 0;
const int bmarg = cb->frame ? qRound(QStyleHelper::dpiScaled(2)) : 0;
const int xpos = x + wi - bmarg - qRound(QStyleHelper::dpiScaled(16));
const int margin = cb->frame ? qRound(QStyleHelper::dpiScaled(3, dpi)) : 0;
const int bmarg = cb->frame ? qRound(QStyleHelper::dpiScaled(2, dpi)) : 0;
const int xpos = x + wi - bmarg - qRound(QStyleHelper::dpiScaled(16, dpi));
switch (sc) {
@ -4258,10 +4259,10 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex
ret = cb->rect;
break;
case SC_ComboBoxArrow:
ret.setRect(xpos, y + bmarg, qRound(QStyleHelper::dpiScaled(16)), he - 2*bmarg);
ret.setRect(xpos, y + bmarg, qRound(QStyleHelper::dpiScaled(16, opt)), he - 2*bmarg);
break;
case SC_ComboBoxEditField:
ret.setRect(x + margin, y + margin, wi - 2 * margin - qRound(QStyleHelper::dpiScaled(16)), he - 2 * margin);
ret.setRect(x + margin, y + margin, wi - 2 * margin - qRound(QStyleHelper::dpiScaled(16, dpi)), he - 2 * margin);
break;
case SC_ComboBoxListBoxPopup:
ret = cb->rect;
@ -4505,13 +4506,13 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
ret = 0;
break;
case PM_DialogButtonsSeparator:
ret = int(QStyleHelper::dpiScaled(5.));
ret = int(QStyleHelper::dpiScaled(5, opt));
break;
case PM_DialogButtonsButtonWidth:
ret = int(QStyleHelper::dpiScaled(70.));
ret = int(QStyleHelper::dpiScaled(70, opt));
break;
case PM_DialogButtonsButtonHeight:
ret = int(QStyleHelper::dpiScaled(30.));
ret = int(QStyleHelper::dpiScaled(30, opt));
break;
case PM_TitleBarHeight: {
if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
@ -4519,33 +4520,33 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
ret = qMax(widget ? widget->fontMetrics().height() : opt->fontMetrics.height(), 16);
#if QT_CONFIG(dockwidget)
} else if (qobject_cast<const QDockWidget*>(widget)) {
ret = qMax(widget->fontMetrics().height(), int(QStyleHelper::dpiScaled(13)));
ret = qMax(widget->fontMetrics().height(), int(QStyleHelper::dpiScaled(13, opt)));
#endif
} else {
ret = qMax(widget ? widget->fontMetrics().height() : opt->fontMetrics.height(), 18);
}
} else {
ret = int(QStyleHelper::dpiScaled(18.));
ret = int(QStyleHelper::dpiScaled(18., opt));
}
break; }
case PM_TitleBarButtonSize:
ret = int(QStyleHelper::dpiScaled(16.));
ret = int(QStyleHelper::dpiScaled(16., opt));
break;
case PM_TitleBarButtonIconSize:
ret = int(QStyleHelper::dpiScaled(16.));
ret = int(QStyleHelper::dpiScaled(16., opt));
break;
case PM_ScrollBarSliderMin:
ret = int(QStyleHelper::dpiScaled(9.));
ret = int(QStyleHelper::dpiScaled(9., opt));
break;
case PM_ButtonMargin:
ret = int(QStyleHelper::dpiScaled(6.));
ret = int(QStyleHelper::dpiScaled(6., opt));
break;
case PM_DockWidgetTitleBarButtonMargin:
ret = int(QStyleHelper::dpiScaled(2.));
ret = int(QStyleHelper::dpiScaled(2., opt));
break;
case PM_ButtonDefaultIndicator:
@ -4553,7 +4554,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_MenuButtonIndicator:
ret = int(QStyleHelper::dpiScaled(12.));
ret = int(QStyleHelper::dpiScaled(12, opt));
break;
case PM_ButtonShiftHorizontal:
@ -4568,15 +4569,15 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
case PM_MenuPanelWidth:
case PM_TabBarBaseOverlap:
case PM_TabBarBaseHeight:
ret = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
ret = proxy()->pixelMetric(PM_DefaultFrameWidth, opt);
break;
case PM_MdiSubWindowFrameWidth:
ret = int(QStyleHelper::dpiScaled(4.));
ret = int(QStyleHelper::dpiScaled(4, opt));
break;
case PM_MdiSubWindowMinimizedWidth:
ret = int(QStyleHelper::dpiScaled(196.));
ret = int(QStyleHelper::dpiScaled(196, opt));
break;
#if QT_CONFIG(scrollbar)
@ -4587,7 +4588,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
: QApplication::globalStrut().width();
ret = qMax(16, s);
} else {
ret = int(QStyleHelper::dpiScaled(16.));
ret = int(QStyleHelper::dpiScaled(16, opt));
}
break;
#endif
@ -4597,7 +4598,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
#if QT_CONFIG(slider)
case PM_SliderThickness:
ret = int(QStyleHelper::dpiScaled(16.));
ret = int(QStyleHelper::dpiScaled(16, opt));
break;
case PM_SliderTickmarkOffset:
@ -4631,11 +4632,11 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
#endif // QT_CONFIG(slider)
#if QT_CONFIG(dockwidget)
case PM_DockWidgetSeparatorExtent:
ret = int(QStyleHelper::dpiScaled(6.));
ret = int(QStyleHelper::dpiScaled(6, opt));
break;
case PM_DockWidgetHandleExtent:
ret = int(QStyleHelper::dpiScaled(8.));
ret = int(QStyleHelper::dpiScaled(8, opt));
break;
case PM_DockWidgetTitleMargin:
ret = 0;
@ -4664,19 +4665,19 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_ToolBarItemSpacing:
ret = int(QStyleHelper::dpiScaled(4.));
ret = int(QStyleHelper::dpiScaled(4, opt));
break;
case PM_ToolBarHandleExtent:
ret = int(QStyleHelper::dpiScaled(8.));
ret = int(QStyleHelper::dpiScaled(8, opt));
break;
case PM_ToolBarSeparatorExtent:
ret = int(QStyleHelper::dpiScaled(6.));
ret = int(QStyleHelper::dpiScaled(6, opt));
break;
case PM_ToolBarExtensionExtent:
ret = int(QStyleHelper::dpiScaled(12.));
ret = int(QStyleHelper::dpiScaled(12, opt));
break;
#endif // QT_CONFIG(toolbar)
@ -4686,7 +4687,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_TabBarTabHSpace:
ret = int(QStyleHelper::dpiScaled(24.));
ret = int(QStyleHelper::dpiScaled(24, opt));
break;
case PM_TabBarTabShiftHorizontal:
@ -4715,27 +4716,27 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_IndicatorWidth:
ret = int(QStyleHelper::dpiScaled(13.));
ret = int(QStyleHelper::dpiScaled(13, opt));
break;
case PM_IndicatorHeight:
ret = int(QStyleHelper::dpiScaled(13.));
ret = int(QStyleHelper::dpiScaled(13, opt));
break;
case PM_ExclusiveIndicatorWidth:
ret = int(QStyleHelper::dpiScaled(12.));
ret = int(QStyleHelper::dpiScaled(12, opt));
break;
case PM_ExclusiveIndicatorHeight:
ret = int(QStyleHelper::dpiScaled(12.));
ret = int(QStyleHelper::dpiScaled(12, opt));
break;
case PM_MenuTearoffHeight:
ret = int(QStyleHelper::dpiScaled(10.));
ret = int(QStyleHelper::dpiScaled(10, opt));
break;
case PM_MenuScrollerHeight:
ret = int(QStyleHelper::dpiScaled(10.));
ret = int(QStyleHelper::dpiScaled(10, opt));
break;
case PM_MenuDesktopFrameWidth:
@ -4745,22 +4746,22 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_HeaderMargin:
ret = int(QStyleHelper::dpiScaled(4.));
ret = int(QStyleHelper::dpiScaled(4, opt));
break;
case PM_HeaderMarkSize:
ret = int(QStyleHelper::dpiScaled(16.));
ret = int(QStyleHelper::dpiScaled(16, opt));
break;
case PM_HeaderGripMargin:
ret = int(QStyleHelper::dpiScaled(4.));
ret = int(QStyleHelper::dpiScaled(4, opt));
break;
case PM_HeaderDefaultSectionSizeHorizontal:
ret = int(QStyleHelper::dpiScaled(100.));
ret = int(QStyleHelper::dpiScaled(100, opt));
break;
case PM_HeaderDefaultSectionSizeVertical:
ret = int(QStyleHelper::dpiScaled(30.));
ret = int(QStyleHelper::dpiScaled(30, opt));
break;
case PM_TabBarScrollButtonWidth:
ret = int(QStyleHelper::dpiScaled(16.));
ret = int(QStyleHelper::dpiScaled(16, opt));
break;
case PM_LayoutLeftMargin:
case PM_LayoutTopMargin:
@ -4782,13 +4783,13 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_DefaultTopLevelMargin:
ret = int(QStyleHelper::dpiScaled(11.));
ret = int(QStyleHelper::dpiScaled(11, opt));
break;
case PM_DefaultChildMargin:
ret = int(QStyleHelper::dpiScaled(9.));
ret = int(QStyleHelper::dpiScaled(9, opt));
break;
case PM_DefaultLayoutSpacing:
ret = int(QStyleHelper::dpiScaled(6.));
ret = int(QStyleHelper::dpiScaled(6, opt));
break;
case PM_ToolBarIconSize:
@ -4796,31 +4797,31 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
ret = theme->themeHint(QPlatformTheme::ToolBarIconSize).toInt();
if (ret <= 0)
ret = int(QStyleHelper::dpiScaled(24.));
ret = int(QStyleHelper::dpiScaled(24, opt));
break;
case PM_TabBarIconSize:
ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
ret = proxy()->pixelMetric(PM_SmallIconSize, opt);
break;
case PM_ListViewIconSize:
#if QT_CONFIG(filedialog)
if (qobject_cast<const QSidebar *>(widget))
ret = int(QStyleHelper::dpiScaled(24.));
ret = int(QStyleHelper::dpiScaled(24., opt));
else
#endif
ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
ret = proxy()->pixelMetric(PM_SmallIconSize, opt);
break;
case PM_ButtonIconSize:
case PM_SmallIconSize:
ret = int(QStyleHelper::dpiScaled(16.));
ret = int(QStyleHelper::dpiScaled(16, opt));
break;
case PM_IconViewIconSize:
ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
ret = proxy()->pixelMetric(PM_LargeIconSize, opt);
break;
case PM_LargeIconSize:
ret = int(QStyleHelper::dpiScaled(32.));
ret = int(QStyleHelper::dpiScaled(32, opt));
break;
case PM_ToolTipLabelFrameWidth:
@ -4828,10 +4829,10 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_CheckBoxLabelSpacing:
case PM_RadioButtonLabelSpacing:
ret = int(QStyleHelper::dpiScaled(6.));
ret = int(QStyleHelper::dpiScaled(6, opt));
break;
case PM_SizeGripSize:
ret = int(QStyleHelper::dpiScaled(13.));
ret = int(QStyleHelper::dpiScaled(13, opt));
break;
case PM_MessageBoxIconSize:
#ifdef Q_OS_MAC
@ -4840,7 +4841,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
} else
#endif
{
ret = int(QStyleHelper::dpiScaled(32.));
ret = int(QStyleHelper::dpiScaled(32, opt));
}
break;
case PM_TextCursorWidth:
@ -4851,19 +4852,19 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_TabCloseIndicatorWidth:
case PM_TabCloseIndicatorHeight:
ret = int(QStyleHelper::dpiScaled(16.));
ret = int(QStyleHelper::dpiScaled(16, opt));
break;
case PM_ScrollView_ScrollBarSpacing:
ret = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
ret = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt);
break;
case PM_ScrollView_ScrollBarOverlap:
ret = 0;
break;
case PM_SubMenuOverlap:
ret = -proxy()->pixelMetric(QStyle::PM_MenuPanelWidth, opt, widget);
ret = -proxy()->pixelMetric(QStyle::PM_MenuPanelWidth, opt);
break;
case PM_TreeViewIndentation:
ret = int(QStyleHelper::dpiScaled(20.));
ret = int(QStyleHelper::dpiScaled(20, opt));
break;
default:
ret = 0;

View File

@ -250,8 +250,9 @@ static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QS
if (rect.isEmpty())
return;
const int arrowWidth = QStyleHelper::dpiScaled(14);
const int arrowHeight = QStyleHelper::dpiScaled(8);
const qreal dpi = QStyleHelper::dpi(option);
const int arrowWidth = int(QStyleHelper::dpiScaled(14, dpi));
const int arrowHeight = int(QStyleHelper::dpiScaled(8, dpi));
const int arrowMax = qMin(arrowHeight, arrowWidth);
const int rectMax = qMin(rect.height(), rect.width());
@ -788,12 +789,13 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding));
} else if (checkbox->state & State_On) {
qreal penWidth = QStyleHelper::dpiScaled(1.5);
const qreal dpi = QStyleHelper::dpi(option);
qreal penWidth = QStyleHelper::dpiScaled(1.5, dpi);
penWidth = qMax<qreal>(penWidth, 0.13 * rect.height());
penWidth = qMin<qreal>(penWidth, 0.20 * rect.height());
QPen checkPen = QPen(checkMarkColor, penWidth);
checkMarkColor.setAlpha(210);
painter->translate(dpiScaled(-0.8), dpiScaled(0.5));
painter->translate(dpiScaled(-0.8, dpi), dpiScaled(0.5, dpi));
painter->setPen(checkPen);
painter->setBrush(Qt::NoBrush);
@ -1544,7 +1546,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
QColor highlight = option->palette.highlight().color();
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
int w = 0;
const int margin = QStyleHelper::dpiScaled(5);
const int margin = int(QStyleHelper::dpiScaled(5, option));
if (!menuItem->text.isEmpty()) {
painter->setFont(menuItem->font);
proxy()->drawItemText(painter, menuItem->rect.adjusted(margin, 0, -margin, 0), Qt::AlignLeft | Qt::AlignVCenter,
@ -1574,7 +1576,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
bool ignoreCheckMark = false;
const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1;
int checkcol = qMax<int>(menuItem->rect.height() * 0.79,
qMax<int>(menuItem->maxIconWidth, dpiScaled(21))); // icon checkbox's highlight column width
qMax<int>(menuItem->maxIconWidth, dpiScaled(21, option))); // icon checkbox's highlight column width
if (
#if QT_CONFIG(combobox)
qobject_cast<const QComboBox*>(widget) ||
@ -1584,7 +1586,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
if (!ignoreCheckMark) {
// Check, using qreal and QRectF to avoid error accumulation
const qreal boxMargin = dpiScaled(3.5);
const qreal boxMargin = dpiScaled(3.5, option);
const qreal boxWidth = checkcol - 2 * boxMargin;
QRectF checkRectF(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth);
QRect checkRect = checkRectF.toRect();
@ -3184,7 +3186,7 @@ int QFusionStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, co
default:
return QCommonStyle::pixelMetric(metric, option, widget);
}
return QStyleHelper::dpiScaled(val);
return QStyleHelper::dpiScaled(val, option);
}
/*!
@ -3236,7 +3238,7 @@ QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *opti
if (menuItem->text.contains(QLatin1Char('\t')))
w += tabSpacing;
else if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu)
w += 2 * QStyleHelper::dpiScaled(QFusionStylePrivate::menuArrowHMargin);
w += 2 * QStyleHelper::dpiScaled(QFusionStylePrivate::menuArrowHMargin, option);
else if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) {
QFontMetrics fm(menuItem->font);
QFont fontBold = menuItem->font;
@ -3244,9 +3246,10 @@ QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *opti
QFontMetrics fmBold(fontBold);
w += fmBold.horizontalAdvance(menuItem->text) - fm.horizontalAdvance(menuItem->text);
}
const int checkcol = qMax<int>(maxpmw, QStyleHelper::dpiScaled(QFusionStylePrivate::menuCheckMarkWidth)); // Windows always shows a check column
const qreal dpi = QStyleHelper::dpi(option);
const int checkcol = qMax<int>(maxpmw, QStyleHelper::dpiScaled(QFusionStylePrivate::menuCheckMarkWidth, dpi)); // Windows always shows a check column
w += checkcol;
w += QStyleHelper::dpiScaled(int(QFusionStylePrivate::menuRightBorder) + 10);
w += QStyleHelper::dpiScaled(int(QFusionStylePrivate::menuRightBorder) + 10, dpi);
newSize.setWidth(w);
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
if (!menuItem->text.isEmpty()) {
@ -3260,8 +3263,8 @@ QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *opti
}
#endif
}
newSize.setWidth(newSize.width() + QStyleHelper::dpiScaled(12));
newSize.setWidth(qMax<int>(newSize.width(), QStyleHelper::dpiScaled(120)));
newSize.setWidth(newSize.width() + int(QStyleHelper::dpiScaled(12, dpi)));
newSize.setWidth(qMax<int>(newSize.width(), int(QStyleHelper::dpiScaled(120, dpi))));
}
break;
case CT_SizeGrip:
@ -3409,7 +3412,7 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom
break;
case SC_SliderGroove: {
QPoint grooveCenter = slider->rect.center();
const int grooveThickness = QStyleHelper::dpiScaled(7);
const int grooveThickness = QStyleHelper::dpiScaled(7, option);
if (slider->orientation == Qt::Horizontal) {
rect.setHeight(grooveThickness);
if (slider->tickPosition & QSlider::TicksAbove)
@ -3438,7 +3441,7 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom
int center = spinbox->rect.height() / 2;
int fw = spinbox->frame ? 3 : 0; // Is drawn with 3 pixels width in drawComplexControl, independently from PM_SpinBoxFrameWidth
int y = fw;
const int buttonWidth = QStyleHelper::dpiScaled(14);
const int buttonWidth = QStyleHelper::dpiScaled(14, option);
int x, lx, rx;
x = spinbox->rect.width() - y - buttonWidth + 2;
lx = fw;
@ -3522,17 +3525,19 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom
case CC_ComboBox:
switch (subControl) {
case SC_ComboBoxArrow:
case SC_ComboBoxArrow: {
const qreal dpi = QStyleHelper::dpi(option);
rect = visualRect(option->direction, option->rect, rect);
rect.setRect(rect.right() - QStyleHelper::dpiScaled(18), rect.top() - 2,
QStyleHelper::dpiScaled(19), rect.height() + 4);
rect.setRect(rect.right() - int(QStyleHelper::dpiScaled(18, dpi)), rect.top() - 2,
int(QStyleHelper::dpiScaled(19, dpi)), rect.height() + 4);
rect = visualRect(option->direction, option->rect, rect);
}
break;
case SC_ComboBoxEditField: {
int frameWidth = 2;
rect = visualRect(option->direction, option->rect, rect);
rect.setRect(option->rect.left() + frameWidth, option->rect.top() + frameWidth,
option->rect.width() - int(QStyleHelper::dpiScaled(19)) - 2 * frameWidth,
option->rect.width() - int(QStyleHelper::dpiScaled(19, option)) - 2 * frameWidth,
option->rect.height() - 2 * frameWidth);
if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
if (!box->editable) {

View File

@ -40,6 +40,8 @@
#include <qstyleoption.h>
#include <qpainter.h>
#include <qpixmapcache.h>
#include <private/qhighdpiscaling_p.h>
#include <private/qguiapplication_p.h>
#include <private/qmath_p.h>
#include <private/qstyle_p.h>
#include <qmath.h>
@ -49,6 +51,7 @@
#include <qabstractscrollarea.h>
#include <qwindow.h>
#include <qmetaobject.h>
#include "qstylehelper_p.h"
#include <qstringbuilder.h>
@ -79,15 +82,41 @@ QString uniqueName(const QString &key, const QStyleOption *option, const QSize &
return tmp;
}
qreal dpiScaled(qreal value)
{
#ifdef Q_OS_MAC
// On mac the DPI is always 72 so we should not scale it
return value;
#ifdef Q_OS_DARWIN
static const qreal qstyleBaseDpi = 72;
#else
static const qreal scale = qreal(qt_defaultDpiX()) / 96.0;
return value * scale;
static const qreal qstyleBaseDpi = 96;
#endif
Q_WIDGETS_EXPORT qreal dpi(const QStyleOption *option)
{
#ifndef Q_OS_DARWIN
// Prioritize the application override, except for on macOS where
// we have historically not supported the AA_Use96Dpi flag.
if (QCoreApplication::testAttribute(Qt::AA_Use96Dpi))
return 96;
#endif
// Expect that QStyleOption::QFontMetrics::QFont has the correct DPI set
if (option)
return option->fontMetrics.fontDpi();
return qstyleBaseDpi;
}
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, qreal dpi)
{
return value * dpi / qstyleBaseDpi;
}
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, const QPaintDevice *device)
{
return dpiScaled(value, device->logicalDpiX());
}
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, const QStyleOption *option)
{
return dpiScaled(value, dpi(option));
}
#ifndef QT_NO_ACCESSIBILITY

View File

@ -40,6 +40,7 @@
#include <QtWidgets/private/qtwidgetsglobal_p.h>
#include <QtCore/qpoint.h>
#include <QtCore/qstring.h>
#include <QtGui/qpaintdevice.h>
#include <QtGui/qpolygon.h>
#include <QtCore/qstringbuilder.h>
#include <QtGui/qaccessible.h>
@ -75,7 +76,13 @@ class QWindow;
namespace QStyleHelper
{
QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size);
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value);
Q_WIDGETS_EXPORT qreal dpi(const QStyleOption *option);
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, qreal dpi);
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, const QPaintDevice *device);
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, const QStyleOption *option);
#if QT_CONFIG(dial)
qreal angle(const QPointF &p1, const QPointF &p2);
QPolygonF calcLines(const QStyleOptionSlider *dial);

View File

@ -423,7 +423,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
ret = QWindowsStylePrivate::fixedPixelMetric(pm);
if (ret != QWindowsStylePrivate::InvalidMetric)
return int(QStyleHelper::dpiScaled(ret));
return int(QStyleHelper::dpiScaled(ret, opt));
ret = 0;
@ -469,7 +469,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
break;
case PM_SplitterWidth:
ret = qMax(int(QStyleHelper::dpiScaled(4)), QApplication::globalStrut().width());
ret = qMax(int(QStyleHelper::dpiScaled(4, opt)), QApplication::globalStrut().width());
break;
default:
@ -793,8 +793,9 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
QPen oldPen = p->pen();
p->setPen(QPen(opt->palette.shadow().color(), 0));
QRectF rect = opt->rect;
const qreal topLevelAdjustment = QStyleHelper::dpiScaled(0.5);
const qreal bottomRightAdjustment = QStyleHelper::dpiScaled(-1.5);
const qreal dpi = QStyleHelper::dpi(opt);
const qreal topLevelAdjustment = QStyleHelper::dpiScaled(0.5, dpi);
const qreal bottomRightAdjustment = QStyleHelper::dpiScaled(-1.5, dpi);
rect.adjust(topLevelAdjustment, topLevelAdjustment,
bottomRightAdjustment, bottomRightAdjustment);
p->drawRect(rect);
@ -2303,8 +2304,9 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
int defwidth = 0;
if (btn->features & QStyleOptionButton::AutoDefaultButton)
defwidth = 2 * proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
int minwidth = int(QStyleHelper::dpiScaled(75.));
int minheight = int(QStyleHelper::dpiScaled(23.));
const qreal dpi = QStyleHelper::dpi(opt);
int minwidth = int(QStyleHelper::dpiScaled(75, dpi));
int minheight = int(QStyleHelper::dpiScaled(23, dpi));
#ifndef QT_QWS_SMALL_PUSHBUTTON
if (w < minwidth + defwidth && !btn->text.isEmpty())