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:
parent
0cae5a4c4b
commit
d7e274a446
@ -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"
|
||||
|
@ -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 |
@ -2,5 +2,6 @@
|
||||
<RCC version="1.0">
|
||||
<qresource>
|
||||
<file>images/testimage.png</file>
|
||||
<file>images/testimage@2x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -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"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user