aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2012-02-14 11:57:25 +1000
committerQt by Nokia <qt-info@nokia.com>2012-02-14 08:50:57 +0100
commitd95178153a0f15991b2e6e91216dbcf5c0be2af3 (patch)
tree26f50195f44f8a5f3ac2757f157e6bfafb6286b6
parent58d85747964473a71ca5339d296d6870f0871b0c (diff)
Preserve aspect ratio when setting Image.sourceSize
Setting both sourceSize.width and sourceSize.height results in changing the image aspect ratio. This is never what you'd want. Fit the image to the provided sourceSize, maintaining the aspect ratio. Task-number: QTBUG-21161 Change-Id: I77e9aacb8d31475d5df0aef1de52c0edbd1e2fc9 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
-rw-r--r--doc/src/declarative/whatsnew.qdoc1
-rw-r--r--src/quick/items/qquickimage.cpp6
-rw-r--r--src/quick/util/qdeclarativepixmapcache.cpp18
-rw-r--r--tests/auto/qtquick2/qquickimage/data/sourceSize.qml7
-rw-r--r--tests/auto/qtquick2/qquickimage/tst_qquickimage.cpp46
5 files changed, 69 insertions, 9 deletions
diff --git a/doc/src/declarative/whatsnew.qdoc b/doc/src/declarative/whatsnew.qdoc
index 4e67bac407..05de859265 100644
--- a/doc/src/declarative/whatsnew.qdoc
+++ b/doc/src/declarative/whatsnew.qdoc
@@ -107,6 +107,7 @@ Added topMargin, bottomMargin, leftMargin, rightMargin, xOrigin, yOrigin propert
Image has two new properties: horizontalAlignment and verticalAlignment. It also has a new value for
fillMode (Image.Pad) that does not transform the image.
+Setting Image sourceSize.width and sourceSize.height will now fit the image to the size, maintaining aspect.
Grid now has rowSpacing and columnSpacing properties.
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index 9af3a7e3ba..a71c666977 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -404,6 +404,10 @@ qreal QQuickImage::paintedHeight() const
other dimension is set in proportion to preserve the source image's aspect ratio.
(The \l fillMode is independent of this.)
+ If both the sourceSize.width and sourceSize.height are set the image will be scaled
+ down to fit within the specified size, maintaining the image's aspect ratio. The actual
+ size of the image after scaling is available via \l implicitWidth and \l implicitHeight.
+
If the source is an intrinsically scalable image (eg. SVG), this property
determines the size of the loaded image regardless of intrinsic size.
Avoid changing this property dynamically; rendering an SVG is \e slow compared
@@ -413,7 +417,7 @@ qreal QQuickImage::paintedHeight() const
be no greater than this property specifies. For some formats (currently only JPEG),
the whole image will never actually be loaded into memory.
- Since QtQuick 1.1 the sourceSize can be cleared to the natural size of the image
+ sourceSize can be cleared to the natural size of the image
by setting sourceSize to \c undefined.
\note \e {Changing this property dynamically causes the image source to be reloaded,
diff --git a/src/quick/util/qdeclarativepixmapcache.cpp b/src/quick/util/qdeclarativepixmapcache.cpp
index 3670c58662..43ce3346cb 100644
--- a/src/quick/util/qdeclarativepixmapcache.cpp
+++ b/src/quick/util/qdeclarativepixmapcache.cpp
@@ -323,20 +323,22 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
force_scale = true;
}
- bool scaled = false;
if (requestSize.width() > 0 || requestSize.height() > 0) {
QSize s = imgio.size();
+ qreal ratio = 0.0;
if (requestSize.width() && (force_scale || requestSize.width() < s.width())) {
- if (requestSize.height() <= 0)
- s.setHeight(s.height()*requestSize.width()/s.width());
- s.setWidth(requestSize.width()); scaled = true;
+ ratio = qreal(requestSize.width())/s.width();
}
if (requestSize.height() && (force_scale || requestSize.height() < s.height())) {
- if (requestSize.width() <= 0)
- s.setWidth(s.width()*requestSize.height()/s.height());
- s.setHeight(requestSize.height()); scaled = true;
+ qreal hr = qreal(requestSize.height())/s.height();
+ if (ratio == 0.0 || hr < ratio)
+ ratio = hr;
+ }
+ if (ratio > 0.0) {
+ s.setHeight(qRound(s.height() * ratio));
+ s.setWidth(qRound(s.width() * ratio));
+ imgio.setScaledSize(s);
}
- if (scaled) { imgio.setScaledSize(s); }
}
if (impsize)
diff --git a/tests/auto/qtquick2/qquickimage/data/sourceSize.qml b/tests/auto/qtquick2/qquickimage/data/sourceSize.qml
new file mode 100644
index 0000000000..8e25c254d3
--- /dev/null
+++ b/tests/auto/qtquick2/qquickimage/data/sourceSize.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+
+Image {
+ source: "heart.png"
+ sourceSize.width: srcWidth
+ sourceSize.height: srcHeight
+}
diff --git a/tests/auto/qtquick2/qquickimage/tst_qquickimage.cpp b/tests/auto/qtquick2/qquickimage/tst_qquickimage.cpp
index b33caa78c4..7602f1b1d5 100644
--- a/tests/auto/qtquick2/qquickimage/tst_qquickimage.cpp
+++ b/tests/auto/qtquick2/qquickimage/tst_qquickimage.cpp
@@ -95,6 +95,8 @@ private slots:
void sourceSize_QTBUG_16389();
void nullPixmapPaint();
void imageCrash_QTBUG_22125();
+ void sourceSize_data();
+ void sourceSize();
private:
QDeclarativeEngine engine;
@@ -498,6 +500,8 @@ void tst_qquickimage::tiling_QTBUG_6716()
QVERIFY(img.pixel(x, y) == qRgb(0, 255, 0));
}
}
+
+ delete canvas;
}
void tst_qquickimage::tiling_QTBUG_6716_data()
@@ -674,6 +678,8 @@ void tst_qquickimage::nullPixmapPaint()
qInstallMsgHandler(previousMsgHandler);
QVERIFY(numberOfWarnings == 0);
delete image;
+
+ delete canvas;
}
void tst_qquickimage::imageCrash_QTBUG_22125()
@@ -698,6 +704,46 @@ void tst_qquickimage::imageCrash_QTBUG_22125()
QCoreApplication::processEvents();
}
+void tst_qquickimage::sourceSize_data()
+{
+ QTest::addColumn<int>("sourceWidth");
+ QTest::addColumn<int>("sourceHeight");
+ QTest::addColumn<qreal>("implicitWidth");
+ QTest::addColumn<qreal>("implicitHeight");
+
+ QTest::newRow("unscaled") << 0 << 0 << 300.0 << 300.0;
+ QTest::newRow("scale width") << 100 << 0 << 100.0 << 100.0;
+ QTest::newRow("scale height") << 0 << 150 << 150.0 << 150.0;
+ QTest::newRow("larger sourceSize") << 400 << 400 << 300.0 << 300.0;
+}
+
+void tst_qquickimage::sourceSize()
+{
+ QFETCH(int, sourceWidth);
+ QFETCH(int, sourceHeight);
+ QFETCH(qreal, implicitWidth);
+ QFETCH(qreal, implicitHeight);
+
+ QQuickView *canvas = new QQuickView(0);
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("srcWidth", sourceWidth);
+ ctxt->setContextProperty("srcHeight", sourceHeight);
+
+ canvas->setSource(testFileUrl("sourceSize.qml"));
+ canvas->show();
+ qApp->processEvents();
+
+ QQuickImage *image = qobject_cast<QQuickImage*>(canvas->rootObject());
+ QVERIFY(image);
+
+ QCOMPARE(image->sourceSize().width(), sourceWidth);
+ QCOMPARE(image->sourceSize().height(), sourceHeight);
+ QCOMPARE(image->implicitWidth(), implicitWidth);
+ QCOMPARE(image->implicitHeight(), implicitHeight);
+
+ delete canvas;
+}
+
QTEST_MAIN(tst_qquickimage)
#include "tst_qquickimage.moc"