summaryrefslogtreecommitdiffstats
path: root/src/widgets/styles
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-04-11 08:48:27 +0200
committerLiang Qi <liang.qi@theqtcompany.com>2016-04-11 09:12:36 +0200
commitf34e73a16a3d757057e007874cb5008f16e20f02 (patch)
treebcc228617cf240773fd09daac1a1a2614b552b68 /src/widgets/styles
parent5380808453728a354ae28aae76e85ac448245cf1 (diff)
parentb9d386f2ccd69c7f6a766a6d90a6024eeb48e90a (diff)
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts: src/corelib/kernel/qobject.cpp src/gui/painting/qpaintengine_raster.cpp Change-Id: I74e1779832f43d033708dcfd6b666c7b4f0111fb
Diffstat (limited to 'src/widgets/styles')
-rw-r--r--src/widgets/styles/qcommonstyle.cpp10
-rw-r--r--src/widgets/styles/qfusionstyle.cpp12
-rw-r--r--src/widgets/styles/qstyleanimation.cpp1
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp6
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp35
-rw-r--r--src/widgets/styles/qwindowsstyle_p_p.h7
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp81
-rw-r--r--src/widgets/styles/qwindowsxpstyle.cpp100
-rw-r--r--src/widgets/styles/qwindowsxpstyle_p_p.h42
9 files changed, 165 insertions, 129 deletions
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 63024360ae..437becbf70 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -803,10 +803,8 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut
default:
return;
}
- QStyleOption arrowOpt;
+ QStyleOption arrowOpt = *toolbutton;
arrowOpt.rect = rect;
- arrowOpt.palette = toolbutton->palette;
- arrowOpt.state = toolbutton->state;
style->drawPrimitive(pe, &arrowOpt, painter, widget);
}
#endif // QT_NO_TOOLBUTTON
@@ -3345,8 +3343,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl
mflags |= State_Sunken;
}
- QStyleOption tool(0);
- tool.palette = toolbutton->palette;
+ QStyleOption tool = *toolbutton;
if (toolbutton->subControls & SC_ToolButton) {
if (bflags & (State_Sunken | State_On | State_Raised)) {
tool.rect = button;
@@ -3415,8 +3412,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl
bool down = false;
QPixmap pm;
- QStyleOption tool(0);
- tool.palette = tb->palette;
+ QStyleOption tool = *tb;
if (tb->subControls & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarCloseButton, widget);
down = tb->activeSubControls & SC_TitleBarCloseButton && (opt->state & State_Sunken);
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index b15b9701d9..5b6e47e2c6 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -1649,7 +1649,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
- QString s = menuitem->text;
+ QStringRef s(&menuitem->text);
if (!s.isEmpty()) { // draw text
p->save();
int t = s.indexOf(QLatin1Char('\t'));
@@ -1660,12 +1660,13 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
if (t >= 0) {
QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ const QString textToDraw = s.mid(t + 1).toString();
if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
p->setPen(menuitem->palette.light().color());
- p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, s.mid(t + 1));
+ p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
p->setPen(discol);
}
- p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ p->drawText(vShortcutRect, text_flags, textToDraw);
s = s.left(t);
}
QFont font = menuitem->font;
@@ -1680,12 +1681,13 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
font.setBold(true);
p->setFont(font);
+ const QString textToDraw = s.left(t).toString();
if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
p->setPen(menuitem->palette.light().color());
- p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, s.left(t));
+ p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
p->setPen(discol);
}
- p->drawText(vTextRect, text_flags, s.left(t));
+ p->drawText(vTextRect, text_flags, textToDraw);
p->restore();
}
diff --git a/src/widgets/styles/qstyleanimation.cpp b/src/widgets/styles/qstyleanimation.cpp
index 67e2ee3225..0b8e32be19 100644
--- a/src/widgets/styles/qstyleanimation.cpp
+++ b/src/widgets/styles/qstyleanimation.cpp
@@ -273,6 +273,7 @@ static QImage blendedImage(const QImage &start, const QImage &end, float alpha)
case 32:
{
blended = QImage(sw, sh, start.format());
+ blended.setDevicePixelRatio(start.devicePixelRatio());
uchar *mixed_data = blended.bits();
const uchar *back_data = start.bits();
const uchar *front_data = end.bits();
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 053820e459..44555c3058 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -3679,7 +3679,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
QRect textRect = subRule.contentsRect(opt->rect);
textRect.setWidth(textRect.width() - mi.tabWidth);
- QString s = mi.text;
+ QStringRef s(&mi.text);
p->setPen(mi.palette.buttonText().color());
if (!s.isEmpty()) {
int text_flags = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
@@ -3689,10 +3689,10 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if (t >= 0) {
QRect vShortcutRect = visualRect(opt->direction, mi.rect,
QRect(textRect.topRight(), QPoint(mi.rect.right(), textRect.bottom())));
- p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ p->drawText(vShortcutRect, text_flags, s.mid(t + 1).toString());
s = s.left(t);
}
- p->drawText(textRect, text_flags, s.left(t));
+ p->drawText(textRect, text_flags, s.left(t).toString());
}
if (mi.menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index fa1ba80402..e0e9d0f6f1 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -71,6 +71,8 @@
#include <private/qstylehelper_p.h>
#include <private/qstyleanimation_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
#if defined(Q_OS_WIN)
@@ -117,8 +119,6 @@ enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
\internal
*/
-int QWindowsStylePrivate::m_appDevicePixelRatio = 0;
-
QWindowsStylePrivate::QWindowsStylePrivate()
: alt_down(false), menuBarTimer(0)
{
@@ -131,11 +131,9 @@ QWindowsStylePrivate::QWindowsStylePrivate()
#endif
}
-int QWindowsStylePrivate::appDevicePixelRatio()
+qreal QWindowsStylePrivate::appDevicePixelRatio()
{
- if (!QWindowsStylePrivate::m_appDevicePixelRatio)
- QWindowsStylePrivate::m_appDevicePixelRatio = qRound(qApp->devicePixelRatio());
- return QWindowsStylePrivate::m_appDevicePixelRatio;
+ return qApp->devicePixelRatio();
}
// Returns \c true if the toplevel parent of \a widget has seen the Alt-key
@@ -163,12 +161,11 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
// Alt has been pressed - find all widgets that care
QList<QWidget *> l = widget->findChildren<QWidget *>();
- for (int pos=0 ; pos < l.size() ; ++pos) {
- QWidget *w = l.at(pos);
- if (w->isWindow() || !w->isVisible() ||
- w->style()->styleHint(SH_UnderlineShortcut, 0, w))
- l.removeAt(pos);
- }
+ auto ignorable = [](QWidget *w) {
+ return w->isWindow() || !w->isVisible()
+ || w->style()->styleHint(SH_UnderlineShortcut, 0, w);
+ };
+ l.erase(std::remove_if(l.begin(), l.end(), ignorable), l.end());
// Update states before repainting
d->seenAlt.append(widget);
d->alt_down = true;
@@ -397,7 +394,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
{
int ret = QWindowsStylePrivate::pixelMetricFromSystemDp(pm, opt, widget);
if (ret != QWindowsStylePrivate::InvalidMetric)
- return ret / QWindowsStylePrivate::devicePixelRatio(widget);
+ return qRound(qreal(ret) / QWindowsStylePrivate::devicePixelRatio(widget));
ret = QWindowsStylePrivate::fixedPixelMetric(pm);
if (ret != QWindowsStylePrivate::InvalidMetric)
@@ -1183,7 +1180,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
- QString s = menuitem->text;
+ QStringRef s(&menuitem->text);
if (!s.isEmpty()) { // draw text
p->save();
int t = s.indexOf(QLatin1Char('\t'));
@@ -1194,24 +1191,26 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
if (t >= 0) {
QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ const QString textToDraw = s.mid(t + 1).toString();
if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
p->setPen(menuitem->palette.light().color());
- p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
+ p->drawText(vShortcutRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
p->setPen(discol);
}
- p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ p->drawText(vShortcutRect, text_flags, textToDraw);
s = s.left(t);
}
QFont font = menuitem->font;
if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
font.setBold(true);
p->setFont(font);
+ const QString textToDraw = s.left(t).toString();
if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
p->setPen(menuitem->palette.light().color());
- p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
+ p->drawText(vTextRect.adjusted(1, 1, 1, 1), text_flags, textToDraw);
p->setPen(discol);
}
- p->drawText(vTextRect, text_flags, s.left(t));
+ p->drawText(vTextRect, text_flags, textToDraw);
p->restore();
}
if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
diff --git a/src/widgets/styles/qwindowsstyle_p_p.h b/src/widgets/styles/qwindowsstyle_p_p.h
index 503cd2ca26..e6c44f401e 100644
--- a/src/widgets/styles/qwindowsstyle_p_p.h
+++ b/src/widgets/styles/qwindowsstyle_p_p.h
@@ -70,8 +70,8 @@ public:
QWindowsStylePrivate();
static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0);
static int fixedPixelMetric(QStyle::PixelMetric pm);
- static int devicePixelRatio(const QWidget *widget = 0)
- { return widget ? int(widget->devicePixelRatioF()) : QWindowsStylePrivate::appDevicePixelRatio(); }
+ static qreal devicePixelRatio(const QWidget *widget = 0)
+ { return widget ? widget->devicePixelRatioF() : QWindowsStylePrivate::appDevicePixelRatio(); }
bool hasSeenAlt(const QWidget *widget) const;
bool altDown() const { return alt_down; }
@@ -96,8 +96,7 @@ public:
};
private:
- static int appDevicePixelRatio();
- static int m_appDevicePixelRatio;
+ static qreal appDevicePixelRatio();
};
QT_END_NAMESPACE
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
index a48417677a..2b2b919818 100644
--- a/src/widgets/styles/qwindowsvistastyle.cpp
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -108,6 +108,15 @@ bool canAnimate(const QStyleOption *option) {
&& !option->styleObject->property("_q_no_animation").toBool();
}
+static inline QImage createAnimationBuffer(const QStyleOption *option, const QWidget *widget)
+{
+ const int devicePixelRatio = widget ? widget->devicePixelRatio() : 1;
+ QImage result(option->rect.size() * devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
+ result.setDevicePixelRatio(devicePixelRatio);
+ result.fill(0);
+ return result;
+}
+
/* \internal
Used by animations to clone a styleoption and shift its offset
*/
@@ -320,12 +329,10 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
// We create separate images for the initial and final transition states and store them in the
// Transition object.
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- startImage.fill(0);
+ QImage startImage = createAnimationBuffer(option, widget);
QPainter startPainter(&startImage);
- QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- endImage.fill(0);
+ QImage endImage = createAnimationBuffer(option, widget);
QPainter endPainter(&endImage);
// If we have a running animation on the widget already, we will use that to paint the initial
@@ -425,8 +432,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
XPThemeData themeSize = theme;
themeSize.partId = TVP_HOTGLYPH;
themeSize.stateId = GLPS_OPENED;
- const QSize size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
- decoration_size = qMax(size.width(), size.height());
+ const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ decoration_size = qRound(qMax(size.width(), size.height()));
}
int mid_h = option->rect.x() + option->rect.width() / 2;
int mid_v = option->rect.y() + option->rect.height() / 2;
@@ -873,8 +880,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QStyleOption *styleOption = clonedAnimationStyleOption(option);
styleOption->state = (QStyle::State)oldState;
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- startImage.fill(0);
+ QImage startImage = createAnimationBuffer(option, widget);
QPainter startPainter(&startImage);
// Use current state of existing animation if already one is running
@@ -886,8 +892,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
}
t->setStartImage(startImage);
- QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- endImage.fill(0);
+ QImage endImage = createAnimationBuffer(option, widget);
QPainter endPainter(&endImage);
styleOption->state = option->state;
proxy()->drawControl(element, styleOption, &endPainter, widget);
@@ -949,10 +954,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject(option)));
if (!anim) {
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- startImage.fill(0);
- QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- alternateImage.fill(0);
+ QImage startImage = createAnimationBuffer(option, widget);
+ QImage alternateImage = createAnimationBuffer(option, widget);
QWindowsVistaPulse *pulse = new QWindowsVistaPulse(styleObject(option));
@@ -991,10 +994,10 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme,
TP_DROPDOWNBUTTON);
if (theme.isValid()) {
- const QSize size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QSizeF size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
if (!size.isEmpty()) {
- mbiw = size.width();
- mbih = size.height();
+ mbiw = qRound(size.width());
+ mbih = qRound(size.height());
}
}
QRect ir = subElementRect(SE_PushButtonContents, option, 0);
@@ -1178,17 +1181,18 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
case CE_MenuItem:
if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
// windows always has a check column, regardless whether we have an icon or not
- int checkcol = 25 / QWindowsXPStylePrivate::devicePixelRatio(widget);
- const int gutterWidth = 3 / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const qreal devicePixelRatio = QWindowsXPStylePrivate::devicePixelRatio(widget);
+ int checkcol = qRound(qreal(25) / devicePixelRatio);
+ const int gutterWidth = qRound(qreal(3) / devicePixelRatio);
{
XPThemeData theme(widget, 0, QWindowsXPStylePrivate::MenuTheme,
MENU_POPUPCHECKBACKGROUND, MBI_HOT);
XPThemeData themeSize = theme;
themeSize.partId = MENU_POPUPCHECK;
themeSize.stateId = 0;
- const QSize size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
- const QMargins margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
- checkcol = qMax(menuitem->maxIconWidth, gutterWidth + size.width() + margins.left() + margins.right());
+ const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ checkcol = qMax(menuitem->maxIconWidth, qRound(gutterWidth + size.width() + margins.left() + margins.right()));
}
QRect rect = option->rect;
@@ -1245,17 +1249,17 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
XPThemeData themeSize = theme;
themeSize.partId = MENU_POPUPCHECK;
themeSize.stateId = 0;
- const QSize size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
- const QMargins margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
- QRect checkRect(0, 0, size.width() + margins.left() + margins.right(),
- size.height() + margins.bottom() + margins.top());
+ const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ QRect checkRect(0, 0, qRound(size.width() + margins.left() + margins.right()),
+ qRound(size.height() + margins.bottom() + margins.top()));
checkRect.moveCenter(vCheckRect.center());
theme.rect = checkRect;
d->drawBackground(theme);
if (menuitem->icon.isNull()) {
- checkRect = QRect(QPoint(0, 0), size);
+ checkRect = QRect(QPoint(0, 0), size.toSize());
checkRect.moveCenter(theme.rect.center());
theme.rect = checkRect;
@@ -1549,13 +1553,10 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle
}
if (doTransition) {
-
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- startImage.fill(0);
+ QImage startImage = createAnimationBuffer(option, widget);
QPainter startPainter(&startImage);
- QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- endImage.fill(0);
+ QImage endImage = createAnimationBuffer(option, widget);
QPainter endPainter(&endImage);
QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject));
@@ -1861,10 +1862,10 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption
XPThemeData themeSize = theme;
themeSize.partId = MENU_POPUPCHECK;
themeSize.stateId = 0;
- const QSize size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
- const QMargins margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
- minimumHeight = qMax(size.height() + margins.bottom() + margins.top(), sz.height());
- sz.rwidth() += size.width() + margins.left() + margins.right();
+ const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ minimumHeight = qMax(qRound(size.height() + margins.bottom() + margins.top()), sz.height());
+ sz.rwidth() += qRound(size.width() + margins.left() + margins.right());
}
if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
@@ -1972,10 +1973,10 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
int arrowWidth = 13;
int arrowHeight = 5;
if (theme.isValid()) {
- const QSize size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QSizeF size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
if (!size.isEmpty()) {
- arrowWidth = size.width();
- arrowHeight = size.height();
+ arrowWidth = qRound(size.width());
+ arrowHeight = qRound(size.height());
}
}
if (option->state & State_Horizontal) {
@@ -2516,7 +2517,7 @@ QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon,
QWindowsXPStylePrivate::ButtonTheme,
BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
if (theme.isValid()) {
- const QSize size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
QIcon linkGlyph;
QPixmap pm(size);
pm.fill(Qt::transparent);
diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp
index c3072303de..1f910d41cb 100644
--- a/src/widgets/styles/qwindowsxpstyle.cpp
+++ b/src/widgets/styles/qwindowsxpstyle.cpp
@@ -431,7 +431,7 @@ const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *widget)
{
if (!tabbody) {
XPThemeData theme(0, 0, QWindowsXPStylePrivate::TabTheme, TABP_BODY);
- const QSize size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
tabbody = new QPixmap(size.width(), QApplication::desktop()->screenGeometry().height());
QPainter painter(tabbody);
@@ -712,6 +712,19 @@ bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels)
return valueChange;
}
+enum TransformType { SimpleTransform, HighDpiScalingTransform, ComplexTransform };
+
+static inline TransformType transformType(const QTransform &transform, qreal devicePixelRatio)
+{
+ if (transform.type() <= QTransform::TxTranslate)
+ return SimpleTransform;
+ if (transform.type() > QTransform::TxScale)
+ return ComplexTransform;
+ return qFuzzyCompare(transform.m11(), devicePixelRatio)
+ && qFuzzyCompare(transform.m22(), devicePixelRatio)
+ ? HighDpiScalingTransform : ComplexTransform;
+}
+
/*! \internal
Main theme drawing function.
Determines the correct lowlevel drawing method depending on several
@@ -735,21 +748,22 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
painter->save();
- bool complexXForm = painter->deviceTransform().type() > QTransform::TxTranslate;
-
// Access paintDevice via engine since the painter may
// return the clip device which can still be a widget device in case of grabWidget().
bool translucentToplevel = false;
const QPaintDevice *paintDevice = painter->device();
+ const qreal aditionalDevicePixelRatio = themeData.widget ? themeData.widget->devicePixelRatio() : 1;
if (paintDevice->devType() == QInternal::Widget) {
const QWidget *window = static_cast<const QWidget *>(paintDevice)->window();
translucentToplevel = window->testAttribute(Qt::WA_TranslucentBackground);
}
+ const TransformType tt = transformType(painter->deviceTransform(), aditionalDevicePixelRatio);
+
bool canDrawDirectly = false;
if (themeData.widget && painter->opacity() == 1.0 && !themeData.rotate
- && !complexXForm && !themeData.mirrorVertically
+ && tt != ComplexTransform && !themeData.mirrorVertically
&& (!themeData.mirrorHorizontally || pDrawThemeBackgroundEx)
&& !translucentToplevel) {
// Draw on backing store DC only for real widgets or backing store images.
@@ -767,26 +781,44 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
}
const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : HDC(0);
- const bool result = dc ? drawBackgroundDirectly(themeData) : drawBackgroundThruNativeBuffer(themeData);
+ const bool result = dc
+ ? drawBackgroundDirectly(dc, themeData, qRound(aditionalDevicePixelRatio))
+ : drawBackgroundThruNativeBuffer(themeData, qRound(aditionalDevicePixelRatio));
painter->restore();
return result;
}
+static inline QRect scaleRect(const QRect &r, int factor)
+{
+ return r.isValid() && factor > 1
+ ? QRect(r.topLeft() * factor, r.size() * factor)
+ : r;
+}
+
+static QRegion scaleRegion(const QRegion &region, int factor)
+{
+ if (region.isEmpty() || factor == 1)
+ return region;
+ if (region.rectCount() == 1)
+ return QRegion(scaleRect(region.boundingRect(), factor));
+ QRegion result;
+ foreach (const QRect &rect, region.rects())
+ result += QRect(rect.topLeft() * factor, rect.size() * factor);
+ return result;
+}
+
/*! \internal
This function draws the theme parts directly to the paintengines HDC.
Do not use this if you need to perform other transformations on the
resulting data.
*/
-bool QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
+bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeData, int additionalDevicePixelRatio)
{
QPainter *painter = themeData.painter;
- HDC dc = 0;
- if (themeData.widget)
- dc = hdcForWidgetBackingStore(themeData.widget);
QPoint redirectionDelta(int(painter->deviceMatrix().dx()),
int(painter->deviceMatrix().dy()));
- QRect area = themeData.rect.translated(redirectionDelta);
+ QRect area = scaleRect(themeData.rect, additionalDevicePixelRatio).translated(redirectionDelta);
QRegion sysRgn = painter->paintEngine()->systemClip();
if (sysRgn.isEmpty())
@@ -794,7 +826,7 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
else
sysRgn &= area;
if (painter->hasClipping())
- sysRgn &= painter->clipRegion().translated(redirectionDelta);
+ sysRgn &= scaleRegion(painter->clipRegion(), additionalDevicePixelRatio).translated(redirectionDelta);
HRGN hrgn = qt_hrgn_from_qregion(sysRgn);
SelectClipRgn(dc, hrgn);
@@ -806,6 +838,7 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
RECT drawRECT = themeData.toRECT(area);
DTBGOPTS drawOptions;
+ memset(&drawOptions, 0, sizeof(drawOptions));
drawOptions.dwSize = sizeof(drawOptions);
drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect());
drawOptions.dwFlags = DTBG_CLIPRECT
@@ -813,8 +846,9 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
| (themeData.noContent ? DTBG_OMITCONTENT : 0)
| (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);
+ HRESULT result = S_FALSE;
if (pDrawThemeBackgroundEx != 0) {
- pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
+ result = pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
} else {
// We are running on a system where the uxtheme.dll does not have
// the DrawThemeBackgroundEx function, so we need to clip away
@@ -848,11 +882,11 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
}
}
- pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));
+ result = pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));
}
SelectClipRgn(dc, 0);
DeleteObject(hrgn);
- return true;
+ return SUCCEEDED(result);
}
/*! \internal
@@ -863,10 +897,11 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
flips (horizonal mirroring only, vertical are handled by the theme
engine).
*/
-bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData)
+bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData,
+ int additionalDevicePixelRatio)
{
QPainter *painter = themeData.painter;
- QRect rect = themeData.rect;
+ QRect rect = scaleRect(themeData.rect, additionalDevicePixelRatio);
if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.
rect = QRect(0, 0, rect.height(), rect.width());
@@ -898,6 +933,8 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
pixmapCacheKey.append(QLatin1Char('w'));
pixmapCacheKey.append(QString::number(h));
pixmapCacheKey.append(QLatin1Char('h'));
+ pixmapCacheKey.append(QString::number(additionalDevicePixelRatio));
+ pixmapCacheKey.append(QLatin1Char('d'));
QPixmap cachedPixmap;
ThemeMapKey key(themeData);
@@ -1074,6 +1111,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa
printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha");
#endif
img = QImage(bufferPixels, bufferW, bufferH, format);
+ img.setDevicePixelRatio(additionalDevicePixelRatio);
}
// Blitting backing store
@@ -2007,7 +2045,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
themeNumber = QWindowsXPStylePrivate::StatusTheme;
partId = SP_GRIPPER;
XPThemeData theme(0, p, themeNumber, partId, 0);
- QSize size = theme.size() / QWindowsStylePrivate::devicePixelRatio(widget);
+ QSize size = (theme.size() / QWindowsStylePrivate::devicePixelRatio(widget)).toSize();
size.rheight()--;
if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) {
switch (sg->corner) {
@@ -2078,7 +2116,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
QWindowsXPStylePrivate::ToolBarTheme,
TP_SPLITBUTTONDROPDOWN);
if (theme.isValid()) {
- const QSize size = theme.size() / QWindowsStylePrivate::devicePixelRatio(widget);
+ const QSize size = (theme.size() / QWindowsStylePrivate::devicePixelRatio(widget)).toSize();
mbiw = size.width();
mbih = size.height();
}
@@ -2541,10 +2579,10 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op
QRect QWindowsXPStylePrivate::scrollBarGripperBounds(QStyle::State flags, const QWidget *widget, XPThemeData *theme)
{
const bool horizontal = flags & QStyle::State_Horizontal;
- const QMargins contentsMargin = theme->margins(theme->rect, TMT_SIZINGMARGINS)
- / QWindowsStylePrivate::devicePixelRatio(widget);
+ const QMargins contentsMargin = (theme->margins(theme->rect, TMT_SIZINGMARGINS)
+ / QWindowsStylePrivate::devicePixelRatio(widget)).toMargins();
theme->partId = horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
- const QSize size = theme->size() / QWindowsStylePrivate::devicePixelRatio(widget);
+ const QSize size = (theme->size() / QWindowsStylePrivate::devicePixelRatio(widget)).toSize();
const int hSpace = theme->rect.width() - size.width();
const int vSpace = theme->rect.height() - size.height();
@@ -3359,7 +3397,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con
int res = QWindowsXPStylePrivate::pixelMetricFromSystemDp(pm, option, widget);
if (res != QWindowsStylePrivate::InvalidMetric)
- return res / QWindowsStylePrivate::devicePixelRatio(widget);
+ return qRound(qreal(res) / QWindowsStylePrivate::devicePixelRatio(widget));
res = 0;
switch (pm) {
@@ -3505,9 +3543,9 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl
const int height = tb->rect.height();
const int width = tb->rect.width();
const int buttonMargin = int(QStyleHelper::dpiScaled(4));
- int buttonHeight = GetSystemMetrics(SM_CYSIZE) / QWindowsStylePrivate::devicePixelRatio(widget)
+ int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) / QWindowsStylePrivate::devicePixelRatio(widget))
- buttonMargin;
- int buttonWidth = GetSystemMetrics(SM_CXSIZE) / QWindowsStylePrivate::devicePixelRatio(widget)
+ int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) / QWindowsStylePrivate::devicePixelRatio(widget))
- buttonMargin;
const int delta = buttonWidth + 2;
int controlTop = option->rect.bottom() - buttonHeight - 2;
@@ -3702,10 +3740,10 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt
{
XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL);
if (buttontheme.isValid()) {
- const QMargins borderSize = buttontheme.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QMarginsF borderSize = buttontheme.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
if (!borderSize.isNull()) {
- sz.rwidth() += borderSize.left() + borderSize.right() - 2;
- sz.rheight() += borderSize.bottom() + borderSize.top() - 2;
+ sz.rwidth() += qRound(borderSize.left() + borderSize.right() - 2);
+ sz.rheight() += qRound(borderSize.bottom() + borderSize.top() - 2);
}
const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1);
sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget)
@@ -3875,7 +3913,7 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt
if (widget && widget->isWindow()) {
XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL);
if (theme.isValid()) {
- const QSize size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(size);
}
}
@@ -3909,7 +3947,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
WP_MAXBUTTON, MAXBS_NORMAL);
if (theme.isValid()) {
- const QSize size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QSize size = (themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
QPixmap pm(size);
pm.fill(Qt::transparent);
QPainter p(&pm);
@@ -3943,7 +3981,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
WP_SMALLCLOSEBUTTON, CBS_NORMAL);
if (theme.isValid()) {
- const QSize size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize();
QPixmap pm(size);
pm.fill(Qt::transparent);
QPainter p(&pm);
@@ -3979,7 +4017,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon,
XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme,
WP_RESTOREBUTTON, RBS_NORMAL);
if (theme.isValid()) {
- const QSize size = themeSize.size() / QWindowsStylePrivate::devicePixelRatio(widget);
+ const QSize size = (themeSize.size() / QWindowsStylePrivate::devicePixelRatio(widget)).toSize();
QPixmap pm(size);
pm.fill(Qt::transparent);
QPainter p(&pm);
diff --git a/src/widgets/styles/qwindowsxpstyle_p_p.h b/src/widgets/styles/qwindowsxpstyle_p_p.h
index 31977304fe..68aa10e12a 100644
--- a/src/widgets/styles/qwindowsxpstyle_p_p.h
+++ b/src/widgets/styles/qwindowsxpstyle_p_p.h
@@ -208,15 +208,15 @@ public:
static RECT toRECT(const QRect &qr);
bool isValid();
- QSize size();
- QMargins margins(const QRect &rect, int propId = TMT_CONTENTMARGINS);
- QMargins margins(int propId = TMT_CONTENTMARGINS);
+ QSizeF size();
+ QMarginsF margins(const QRect &rect, int propId = TMT_CONTENTMARGINS);
+ QMarginsF margins(int propId = TMT_CONTENTMARGINS);
- static QSize themeSize(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, int part = 0, int state = 0);
- static QMargins themeMargins(const QRect &rect, const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
- int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS);
- static QMargins themeMargins(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
- int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS);
+ static QSizeF themeSize(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, int part = 0, int state = 0);
+ static QMarginsF themeMargins(const QRect &rect, const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
+ int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS);
+ static QMarginsF themeMargins(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1,
+ int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS);
const QWidget *widget;
QPainter *painter;
@@ -393,8 +393,8 @@ public:
void setTransparency(QWidget *widget, XPThemeData &themeData);
bool drawBackground(XPThemeData &themeData);
- bool drawBackgroundThruNativeBuffer(XPThemeData &themeData);
- bool drawBackgroundDirectly(XPThemeData &themeData);
+ bool drawBackgroundThruNativeBuffer(XPThemeData &themeData, int aditionalDevicePixelRatio);
+ bool drawBackgroundDirectly(HDC dc, XPThemeData &themeData, int aditionalDevicePixelRatio);
bool hasAlphaChannel(const QRect &rect);
bool fixAlphaChannel(const QRect &rect);
@@ -433,9 +433,9 @@ private:
static HTHEME m_themes[NThemes];
};
-inline QSize XPThemeData::size()
+inline QSizeF XPThemeData::size()
{
- QSize result(0, 0);
+ QSizeF result(0, 0);
if (isValid()) {
SIZE size;
if (SUCCEEDED(QWindowsXPStylePrivate::pGetThemePartSize(handle(), 0, partId, stateId, 0, TS_TRUE, &size)))
@@ -444,9 +444,9 @@ inline QSize XPThemeData::size()
return result;
}
-inline QMargins XPThemeData::margins(const QRect &qRect, int propId)
+inline QMarginsF XPThemeData::margins(const QRect &qRect, int propId)
{
- QMargins result(0, 0, 0 ,0);
+ QMarginsF result(0, 0, 0 ,0);
if (isValid()) {
MARGINS margins;
RECT rect = XPThemeData::toRECT(qRect);
@@ -456,9 +456,9 @@ inline QMargins XPThemeData::margins(const QRect &qRect, int propId)
return result;
}
-inline QMargins XPThemeData::margins(int propId)
+inline QMarginsF XPThemeData::margins(int propId)
{
- QMargins result(0, 0, 0 ,0);
+ QMarginsF result(0, 0, 0 ,0);
if (isValid()) {
MARGINS margins;
if (SUCCEEDED(QWindowsXPStylePrivate::pGetThemeMargins(handle(), 0, partId, stateId, propId, NULL, &margins)))
@@ -467,21 +467,21 @@ inline QMargins XPThemeData::margins(int propId)
return result;
}
-inline QSize XPThemeData::themeSize(const QWidget *w, QPainter *p, int themeIn, int part, int state)
+inline QSizeF XPThemeData::themeSize(const QWidget *w, QPainter *p, int themeIn, int part, int state)
{
XPThemeData theme(w, p, themeIn, part, state);
return theme.size();
}
-inline QMargins XPThemeData::themeMargins(const QRect &rect, const QWidget *w, QPainter *p, int themeIn,
- int part, int state, int propId)
+inline QMarginsF XPThemeData::themeMargins(const QRect &rect, const QWidget *w, QPainter *p, int themeIn,
+ int part, int state, int propId)
{
XPThemeData theme(w, p, themeIn, part, state);
return theme.margins(rect, propId);
}
-inline QMargins XPThemeData::themeMargins(const QWidget *w, QPainter *p, int themeIn,
- int part, int state, int propId)
+inline QMarginsF XPThemeData::themeMargins(const QWidget *w, QPainter *p, int themeIn,
+ int part, int state, int propId)
{
XPThemeData theme(w, p, themeIn, part, state);
return theme.margins(propId);