QStyle: let styleCachePixmap() use the correct devicePixelRatio

The helper function styleCachePixmap() might not be using the correct
dpr. It was written in a time when there was only one application-wide
dpr available but nowadays we have to use the dpr from the paintDevice
we paint on instead.
As a drive-by replace the one usage of styleCacheImage() by
styleCachePixmap() and remove the now superfluous function.

Change-Id: I14eb3fd3bad7f9299d42b63b03fa1f68b4f81cd6
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
This commit is contained in:
Christian Ehrlicher 2024-04-19 20:38:43 +02:00
parent cbed43982c
commit c6c6dc471c
2 changed files with 17 additions and 29 deletions

View File

@ -145,6 +145,7 @@ static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QS
return; return;
const qreal dpi = QStyleHelper::dpi(option); const qreal dpi = QStyleHelper::dpi(option);
const qreal dpr = painter->device()->devicePixelRatio();
const int arrowWidth = int(QStyleHelper::dpiScaled(14, dpi)); const int arrowWidth = int(QStyleHelper::dpiScaled(14, dpi));
const int arrowHeight = int(QStyleHelper::dpiScaled(8, dpi)); const int arrowHeight = int(QStyleHelper::dpiScaled(8, dpi));
@ -158,8 +159,7 @@ static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QS
% HexString<uint>(color.rgba()), % HexString<uint>(color.rgba()),
option, rect.size()); option, rect.size());
if (!QPixmapCache::find(cacheKey, &cachePixmap)) { if (!QPixmapCache::find(cacheKey, &cachePixmap)) {
cachePixmap = styleCachePixmap(rect.size()); cachePixmap = styleCachePixmap(rect.size(), dpr);
cachePixmap.fill(Qt::transparent);
QPainter cachePainter(&cachePixmap); QPainter cachePainter(&cachePixmap);
QRectF arrowRect; QRectF arrowRect;
@ -1138,6 +1138,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
const QStyleOptionHeaderV2 *headerV2 = qstyleoption_cast<const QStyleOptionHeaderV2 *>(option); const QStyleOptionHeaderV2 *headerV2 = qstyleoption_cast<const QStyleOptionHeaderV2 *>(option);
const bool isSectionDragTarget = headerV2 ? headerV2->isSectionDragTarget : false; const bool isSectionDragTarget = headerV2 ? headerV2->isSectionDragTarget : false;
const qreal dpr = painter->device()->devicePixelRatio();
const QString pixmapName = QStyleHelper::uniqueName("headersection-"_L1 const QString pixmapName = QStyleHelper::uniqueName("headersection-"_L1
% HexString(header->position) % HexString(header->position)
% HexString(header->orientation) % HexString(header->orientation)
@ -1145,8 +1146,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
option, option->rect.size()); option, option->rect.size());
QPixmap cache; QPixmap cache;
if (!QPixmapCache::find(pixmapName, &cache)) { if (!QPixmapCache::find(pixmapName, &cache)) {
cache = styleCachePixmap(rect.size()); cache = styleCachePixmap(rect.size(), dpr);
cache.fill(Qt::transparent);
QRect pixmapRect(0, 0, rect.width(), rect.height()); QRect pixmapRect(0, 0, rect.width(), rect.height());
QPainter cachePainter(&cache); QPainter cachePainter(&cache);
QColor buttonColor = d->buttonColor(option->palette); QColor buttonColor = d->buttonColor(option->palette);
@ -1879,12 +1879,12 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
#if QT_CONFIG(spinbox) #if QT_CONFIG(spinbox)
case CC_SpinBox: case CC_SpinBox:
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
const qreal dpr = painter->device()->devicePixelRatio();
QPixmap cache; QPixmap cache;
QString pixmapName = QStyleHelper::uniqueName("spinbox"_L1, spinBox, spinBox->rect.size()); QString pixmapName = QStyleHelper::uniqueName("spinbox"_L1, spinBox, spinBox->rect.size());
if (!QPixmapCache::find(pixmapName, &cache)) { if (!QPixmapCache::find(pixmapName, &cache)) {
cache = styleCachePixmap(spinBox->rect.size()); cache = styleCachePixmap(spinBox->rect.size(), dpr);
cache.fill(Qt::transparent);
QRect pixmapRect(0, 0, spinBox->rect.width(), spinBox->rect.height()); QRect pixmapRect(0, 0, spinBox->rect.width(), spinBox->rect.height());
QRect rect = pixmapRect; QRect rect = pixmapRect;
@ -2576,6 +2576,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
bool hasFocus = option->state & State_HasFocus && option->state & State_KeyboardFocusChange; bool hasFocus = option->state & State_HasFocus && option->state & State_KeyboardFocusChange;
bool sunken = comboBox->state & State_On; // play dead, if combobox has no items bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
bool isEnabled = (comboBox->state & State_Enabled); bool isEnabled = (comboBox->state & State_Enabled);
const qreal dpr = painter->device()->devicePixelRatio();
QPixmap cache; QPixmap cache;
const QString pixmapName = QStyleHelper::uniqueName("combobox"_L1 const QString pixmapName = QStyleHelper::uniqueName("combobox"_L1
% QLatin1StringView(sunken ? "-sunken" : "") % QLatin1StringView(sunken ? "-sunken" : "")
@ -2584,8 +2585,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
% QLatin1StringView(!comboBox->frame ? "-frameless" : ""), % QLatin1StringView(!comboBox->frame ? "-frameless" : ""),
option, comboBox->rect.size()); option, comboBox->rect.size());
if (!QPixmapCache::find(pixmapName, &cache)) { if (!QPixmapCache::find(pixmapName, &cache)) {
cache = styleCachePixmap(comboBox->rect.size()); cache = styleCachePixmap(comboBox->rect.size(), dpr);
cache.fill(Qt::transparent);
QPainter cachePainter(&cache); QPainter cachePainter(&cache);
QRect pixmapRect(0, 0, comboBox->rect.width(), comboBox->rect.height()); QRect pixmapRect(0, 0, comboBox->rect.width(), comboBox->rect.height());
QStyleOptionComboBox comboBoxCopy = *comboBox; QStyleOptionComboBox comboBoxCopy = *comboBox;
@ -2673,6 +2673,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
#if QT_CONFIG(slider) #if QT_CONFIG(slider)
case CC_Slider: case CC_Slider:
if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
const qreal dpr = painter->device()->devicePixelRatio();
QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget); QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget); QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
@ -2699,8 +2700,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
// draw background groove // draw background groove
if (!QPixmapCache::find(groovePixmapName, &cache)) { if (!QPixmapCache::find(groovePixmapName, &cache)) {
cache = styleCachePixmap(pixmapRect.size()); cache = styleCachePixmap(pixmapRect.size(), dpr);
cache.fill(Qt::transparent);
QPainter groovePainter(&cache); QPainter groovePainter(&cache);
groovePainter.setRenderHint(QPainter::Antialiasing, true); groovePainter.setRenderHint(QPainter::Antialiasing, true);
groovePainter.translate(0.5, 0.5); groovePainter.translate(0.5, 0.5);
@ -2728,8 +2728,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
if (!groovePixmapName.isEmpty()) if (!groovePixmapName.isEmpty())
groovePixmapName += "_blue"_L1; groovePixmapName += "_blue"_L1;
if (!QPixmapCache::find(groovePixmapName, &cache)) { if (!QPixmapCache::find(groovePixmapName, &cache)) {
cache = styleCachePixmap(pixmapRect.size()); cache = styleCachePixmap(pixmapRect.size(), dpr);
cache.fill(Qt::transparent);
QPainter groovePainter(&cache); QPainter groovePainter(&cache);
QLinearGradient gradient; QLinearGradient gradient;
if (horizontal) { if (horizontal) {
@ -2841,8 +2840,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
if ((option->subControls & SC_SliderHandle) ) { if ((option->subControls & SC_SliderHandle) ) {
QString handlePixmapName = QStyleHelper::uniqueName("slider_handle"_L1, option, handle.size()); QString handlePixmapName = QStyleHelper::uniqueName("slider_handle"_L1, option, handle.size());
if (!QPixmapCache::find(handlePixmapName, &cache)) { if (!QPixmapCache::find(handlePixmapName, &cache)) {
cache = styleCachePixmap(handle.size()); cache = styleCachePixmap(handle.size(), dpr);
cache.fill(Qt::transparent);
QRect pixmapRect(0, 0, handle.width(), handle.height()); QRect pixmapRect(0, 0, handle.width(), handle.height());
QPainter handlePainter(&cache); QPainter handlePainter(&cache);
QRect gradRect = pixmapRect.adjusted(2, 2, -2, -2); QRect gradRect = pixmapRect.adjusted(2, 2, -2, -2);

View File

@ -35,27 +35,19 @@ public:
QString name; QString name;
}; };
inline QImage styleCacheImage(const QSize &size) inline QPixmap styleCachePixmap(const QSize &size, qreal pixelRatio)
{ {
const qreal pixelRatio = qApp->devicePixelRatio();
QImage cacheImage = QImage(size * pixelRatio, QImage::Format_ARGB32_Premultiplied);
cacheImage.setDevicePixelRatio(pixelRatio);
return cacheImage;
}
inline QPixmap styleCachePixmap(const QSize &size)
{
const qreal pixelRatio = qApp->devicePixelRatio();
QPixmap cachePixmap = QPixmap(size * pixelRatio); QPixmap cachePixmap = QPixmap(size * pixelRatio);
cachePixmap.setDevicePixelRatio(pixelRatio); cachePixmap.setDevicePixelRatio(pixelRatio);
cachePixmap.fill(Qt::transparent);
return cachePixmap; return cachePixmap;
} }
#define BEGIN_STYLE_PIXMAPCACHE(a) \ #define BEGIN_STYLE_PIXMAPCACHE(a) \
QRect rect = option->rect; \ QRect rect = option->rect; \
QPixmap internalPixmapCache; \ QPixmap internalPixmapCache; \
QImage imageCache; \
QPainter *p = painter; \ QPainter *p = painter; \
const auto dpr = p->device()->devicePixelRatio(); \
const QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \ const QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \
int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \ int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \
const bool doPixmapCache = (!option->rect.isEmpty()) \ const bool doPixmapCache = (!option->rect.isEmpty()) \
@ -65,9 +57,8 @@ inline QPixmap styleCachePixmap(const QSize &size)
} else { \ } else { \
if (doPixmapCache) { \ if (doPixmapCache) { \
rect.setRect(0, 0, option->rect.width(), option->rect.height()); \ rect.setRect(0, 0, option->rect.width(), option->rect.height()); \
imageCache = styleCacheImage(option->rect.size()); \ internalPixmapCache = styleCachePixmap(option->rect.size(), dpr); \
imageCache.fill(0); \ p = new QPainter(&internalPixmapCache); \
p = new QPainter(&imageCache); \
} }
@ -76,7 +67,6 @@ inline QPixmap styleCachePixmap(const QSize &size)
if (doPixmapCache) { \ if (doPixmapCache) { \
p->end(); \ p->end(); \
delete p; \ delete p; \
internalPixmapCache = QPixmap::fromImage(imageCache); \
painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \ painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
QPixmapCache::insert(unique, internalPixmapCache); \ QPixmapCache::insert(unique, internalPixmapCache); \
} \ } \