StyleSheetStyle: Load @Nx images

Perform a @Nx image file lookup when loading pixmaps.

Make drawBackgroundImage() handle high-dpi pixmaps,
here the layout calculations needs to be in device-
independent pixels

Fixes: QTBUG-36825
Change-Id: I61e6f53c59f61f3bd88c34a036349e51e8c8ad92
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
This commit is contained in:
Morten Johan Sørvig 2014-03-13 09:10:47 +01:00 committed by Ulf Hermann
parent 0cae5a4c4b
commit d7e274a446
6 changed files with 73 additions and 9 deletions

View File

@ -115,6 +115,8 @@
#include <QtWidgets/qtoolbar.h>
#endif
#include <QtGui/qscreen.h>
QT_BEGIN_NAMESPACE
using namespace QCss;
@ -952,8 +954,10 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
Attachment attachment = Attachment_Scroll;
origin = Origin_Padding;
Origin clip = Origin_Border;
if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip))
bg = new QStyleSheetBackgroundData(brush, QPixmap(uri), repeat, alignment, origin, attachment, clip);
if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip)) {
bg = new QStyleSheetBackgroundData(brush, QStyleSheetStyle::loadPixmap(uri, object),
repeat, alignment, origin, attachment, clip);
}
QBrush sfg, fg;
QBrush sbg, abg;
@ -992,7 +996,7 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
bd->bi = new QStyleSheetBorderImageData;
QStyleSheetBorderImageData *bi = bd->bi;
bi->pixmap = QPixmap(uri);
bi->pixmap = QStyleSheetStyle::loadPixmap(uri, object);
for (int i = 0; i < 4; i++)
bi->cuts[i] = cuts[i];
bi->horizStretch = horizStretch;
@ -1215,30 +1219,33 @@ void QRenderRule::drawBackgroundImage(QPainter *p, const QRect &rect, QPoint off
if (background()->attachment == Attachment_Fixed)
off = QPoint(0, 0);
QSize bgpSize = bgp.size() / bgp.devicePixelRatio();
int bgpHeight = bgpSize.height();
int bgpWidth = bgpSize.width();
QRect r = originRect(rect, background()->origin);
QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgp.size(), r);
QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgpSize, r);
QRect inter = aligned.translated(-off).intersected(r);
switch (background()->repeat) {
case Repeat_Y:
p->drawTiledPixmap(inter.x(), r.y(), inter.width(), r.height(), bgp,
inter.x() - aligned.x() + off.x(),
bgp.height() - int(aligned.y() - r.y()) % bgp.height() + off.y());
bgpHeight - int(aligned.y() - r.y()) % bgpHeight + off.y());
break;
case Repeat_X:
p->drawTiledPixmap(r.x(), inter.y(), r.width(), inter.height(), bgp,
bgp.width() - int(aligned.x() - r.x())%bgp.width() + off.x(),
bgpWidth - int(aligned.x() - r.x())%bgpWidth + off.x(),
inter.y() - aligned.y() + off.y());
break;
case Repeat_XY:
p->drawTiledPixmap(r, bgp,
QPoint(bgp.width() - int(aligned.x() - r.x())% bgp.width() + off.x(),
bgp.height() - int(aligned.y() - r.y())%bgp.height() + off.y()));
QPoint(bgpWidth - int(aligned.x() - r.x())% bgpWidth + off.x(),
bgpHeight - int(aligned.y() - r.y())%bgpHeight + off.y()));
break;
case Repeat_None:
default:
p->drawPixmap(inter.x(), inter.y(), bgp, inter.x() - aligned.x() + off.x(),
inter.y() - aligned.y() + off.y(), inter.width(), inter.height());
inter.y() - aligned.y() + off.y(), bgp.width() , bgp.height());
break;
}
@ -6107,6 +6114,28 @@ bool QStyleSheetStyle::isNaturalChild(const QObject *obj)
return false;
}
QPixmap QStyleSheetStyle::loadPixmap(const QString &fileName, const QObject *context)
{
qreal ratio = -1.0;
if (const QWidget *widget = qobject_cast<const QWidget *>(context)) {
if (QScreen *screen = QApplication::screenAt(widget->mapToGlobal(QPoint(0, 0))))
ratio = screen->devicePixelRatio();
}
if (ratio < 0) {
if (const QApplication *app = qApp)
ratio = app->devicePixelRatio();
else
ratio = 1.0;
}
qreal sourceDevicePixelRatio = 1.0;
QString resolvedFileName = qt_findAtNxFile(fileName, ratio, &sourceDevicePixelRatio);
QPixmap pixmap(resolvedFileName);
pixmap.setDevicePixelRatio(sourceDevicePixelRatio);
return pixmap;
}
QT_END_NAMESPACE
#include "moc_qstylesheetstyle_p.cpp"

View File

@ -167,6 +167,7 @@ private:
static Qt::Alignment resolveAlignment(Qt::LayoutDirection, Qt::Alignment);
static bool isNaturalChild(const QObject *obj);
static QPixmap loadPixmap(const QString &fileName, const QObject *context);
bool initObject(const QObject *obj) const;
public:
static int numinstances;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View File

@ -2,5 +2,6 @@
<RCC version="1.0">
<qresource>
<file>images/testimage.png</file>
<file>images/testimage@2x.png</file>
</qresource>
</RCC>

View File

@ -33,6 +33,7 @@
#include <QMetaObject>
#include <private/qstylesheetstyle_p.h>
#include <private/qhighdpiscaling_p.h>
#include <QtTest/private/qtesthelpers_p.h>
using namespace QTestPrivate;
@ -101,6 +102,9 @@ private slots:
void styleSheetTargetAttribute();
void unpolish();
void highdpiImages_data();
void highdpiImages();
private:
QColor COLOR(const QWidget& w) {
w.ensurePolished();
@ -2066,6 +2070,35 @@ void tst_QStyleSheetStyle::unpolish()
QCOMPARE(w.minimumWidth(), 0);
}
void tst_QStyleSheetStyle::highdpiImages_data()
{
QTest::addColumn<qreal>("screenFactor");
QTest::addColumn<QColor>("color");
QTest::newRow("highdpi") << 2.0 << QColor(0x00, 0xFF, 0x00);
QTest::newRow("lowdpi") << 1.0 << QColor(0xFF, 0x00, 0x00);
}
void tst_QStyleSheetStyle::highdpiImages()
{
QFETCH(qreal, screenFactor);
QFETCH(QColor, color);
QWidget w;
QScreen *screen = QGuiApplication::screenAt(w.pos());
QHighDpiScaling::setScreenFactor(screen, screenFactor);
w.setStyleSheet("QWidget { background-image: url(\":/images/testimage.png\"); }");
w.show();
QVERIFY(QTest::qWaitForWindowExposed(&w));
QImage image(w.size(), QImage::Format_ARGB32);
w.render(&image);
QVERIFY(testForColors(image, color));
QHighDpiScaling::setScreenFactor(screen, 1.0);
QHighDpiScaling::updateHighDpiScaling(); // reset to normal
}
QTEST_MAIN(tst_QStyleSheetStyle)
#include "tst_qstylesheetstyle.moc"