aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickimage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items/qquickimage.cpp')
-rw-r--r--src/quick/items/qquickimage.cpp396
1 files changed, 242 insertions, 154 deletions
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index 49e5b7b1fa..3efe082332 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qquickimage_p.h"
#include "qquickimage_p_p.h"
@@ -52,52 +16,32 @@
QT_BEGIN_NAMESPACE
-class QQuickImageTextureProvider : public QSGTextureProvider
+QQuickImageTextureProvider::QQuickImageTextureProvider()
+ : m_texture(nullptr)
+ , m_smooth(false)
{
- Q_OBJECT
-public:
- QQuickImageTextureProvider()
- : m_texture(nullptr)
- , m_smooth(false)
- {
- }
+}
- void updateTexture(QSGTexture *texture) {
- if (m_texture == texture)
- return;
- m_texture = texture;
- emit textureChanged();
- }
+void QQuickImageTextureProvider::updateTexture(QSGTexture *texture) {
+ if (m_texture == texture)
+ return;
+ m_texture = texture;
+ emit textureChanged();
+}
- QSGTexture *texture() const override {
- if (m_texture) {
- m_texture->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest);
- m_texture->setMipmapFiltering(m_mipmap ? QSGTexture::Linear : QSGTexture::None);
- m_texture->setHorizontalWrapMode(QSGTexture::ClampToEdge);
- m_texture->setVerticalWrapMode(QSGTexture::ClampToEdge);
- }
- return m_texture;
+QSGTexture *QQuickImageTextureProvider::texture() const {
+ if (m_texture) {
+ m_texture->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest);
+ m_texture->setMipmapFiltering(m_mipmap ? QSGTexture::Linear : QSGTexture::None);
+ m_texture->setHorizontalWrapMode(QSGTexture::ClampToEdge);
+ m_texture->setVerticalWrapMode(QSGTexture::ClampToEdge);
}
-
- friend class QQuickImage;
-
- QSGTexture *m_texture;
- bool m_smooth;
- bool m_mipmap;
-};
-
-#include "qquickimage.moc"
-#include "moc_qquickimage_p.cpp"
+ return m_texture;
+}
QQuickImagePrivate::QQuickImagePrivate()
- : fillMode(QQuickImage::Stretch)
- , paintedWidth(0)
- , paintedHeight(0)
- , pixmapChanged(false)
+ : pixmapChanged(false)
, mipmap(false)
- , hAlign(QQuickImage::AlignHCenter)
- , vAlign(QQuickImage::AlignVCenter)
- , provider(nullptr)
{
}
@@ -135,27 +79,79 @@ QQuickImagePrivate::QQuickImagePrivate()
\clearfloat
- \section1 OpenGL Texture Files
+ \section1 Compressed Texture Files
- When the default OpenGL \l{Qt Quick Scene Graph}{scene graph} backend is in
- use, images can also be supplied in compressed texture files. The content
- must be a simple RGB(A) format 2D texture. Supported compression schemes
- are only limited by the underlying OpenGL driver and GPU. The following
- container file formats are supported:
+ When supported by the implementation of the underlying graphics API at run
+ time, images can also be supplied in compressed texture files. The content
+ must be a simple RGB(A) format 2D texture. Supported compression schemes are
+ only limited by the underlying driver and GPU. The following container file
+ formats are supported:
\list
\li \c PKM (since Qt 5.10)
\li \c KTX (since Qt 5.11)
+ \li \c ASTC (since Qt 5.13)
\endlist
+ \note The intended vertical orientation of an image in a texture file is not generally well
+ defined. Different texture compression tools have different defaults and options of when to
+ perform vertical flipping of the input image. If an image from a texture file appears upside
+ down, flipping may need to be toggled in the asset conditioning process. Alternatively, the
+ Image element itself can be flipped by either applying a suitable transformation via the
+ transform property or, more conveniently, by setting the mirrorVertically property:
+ \badcode
+ transform: [ Translate { y: -myImage.height }, Scale { yScale: -1 } ]
+ \endcode
+ or
+ \badcode
+ mirrorVertically: true
+ \endcode
+
\note Semi-transparent original images require alpha pre-multiplication
prior to texture compression in order to be correctly displayed in Qt
Quick. This can be done with the following ImageMagick command
line:
\badcode
- convert MYORIGIMAGE \( +clone -alpha Extract \) -channel RGB -compose Multiply -composite MYPMIMAGE
+ convert foo.png \( +clone -alpha Extract \) -channel RGB -compose Multiply -composite foo_pm.png
\endcode
+ Do not confuse container formats, such as, \c KTX, and the format of the
+ actual texture data stored in the container file. For example, reading a
+ \c KTX file is supported on all platforms, independently of what GPU driver is
+ used at run time. However, this does not guarantee that the compressed
+ texture format, used by the data in the file, is supported at run time. For
+ example, if the KTX file contains compressed data with the format
+ \c{ETC2 RGBA8}, and the 3D graphics API implementation used at run time does not
+ support \c ETC2 compressed textures, the Image item will not display
+ anything.
+
+ \note Compressed texture format support is not under Qt's control, and it
+ is up to the application or device developer to ensure the compressed
+ texture data is provided in the appropriate format for the target
+ environment(s).
+
+ Do not assume that compressed format support is specific to a platform. It
+ may also be specific to the driver and 3D API implementation in use on that
+ particular platform. In practice, implementations of different 3D graphics
+ APIs (e.g., Vulkan and OpenGL) on the same platform (e.g., Windows) from
+ the same vendor for the same hardware may offer a different set of
+ compressed texture formats.
+
+ When targeting desktop environments (Windows, macOS, Linux) only, a general
+ recommendation is to consider using the \c{DXTn}/\c{BCn} formats since
+ these tend to have the widest support amongst the implementations of Direct
+ 3D, Vulkan, OpenGL, and Metal on these platforms. In contrast, when
+ targeting mobile or embedded devices, the \c ETC2 or \c ASTC formats are
+ likely to be a better choice since these are typically the formats
+ supported by the OpenGL ES implementations on such hardware.
+
+ An application that intends to run across desktop, mobile, and embedded
+ hardware should plan and design its use of compressed textures carefully.
+ It is highly likely that relying on a single format is not going to be
+ sufficient, and therefore the application will likely need to branch based
+ on the platform to use compressed textures in a format appropriate there,
+ or perhaps to skip using compressed textures in some cases.
+
\section1 Automatic Detection of File Extension
If the \l source URL indicates a non-existing local file or resource, the
@@ -163,10 +159,10 @@ QQuickImagePrivate::QQuickImagePrivate()
file can be found by appending any of the supported image file extensions
to the \l source URL, then that file will be loaded.
- If the OpenGL \l{Qt Quick Scene Graph}{scene graph} backend is in use, the
- file search the attempts the OpenGL texture file extensions first. If the
- search is unsuccessful, it attempts to search with the file extensions for
- the \l{QImageReader::supportedImageFormats()}{conventional image file
+ The file search attempts to look for compressed texture container file
+ extensions first. If the search is unsuccessful, it attempts to search with
+ the file extensions for the
+ \l{QImageReader::supportedImageFormats()}{conventional image file
types}. For example:
\snippet qml/image-ext.qml ext
@@ -222,22 +218,16 @@ QQuickImage::~QQuickImage()
void QQuickImagePrivate::setImage(const QImage &image)
{
Q_Q(QQuickImage);
- pix.setImage(image);
-
+ currentPix->setImage(image);
q->pixmapChange();
- status = pix.isNull() ? QQuickImageBase::Null : QQuickImageBase::Ready;
-
q->update();
}
void QQuickImagePrivate::setPixmap(const QQuickPixmap &pixmap)
{
Q_Q(QQuickImage);
- pix.setPixmap(pixmap);
-
+ currentPix->setPixmap(pixmap);
q->pixmapChange();
- status = pix.isNull() ? QQuickImageBase::Null : QQuickImageBase::Ready;
-
q->update();
}
@@ -246,15 +236,15 @@ void QQuickImagePrivate::setPixmap(const QQuickPixmap &pixmap)
Set this property to define what happens when the source image has a different size
than the item.
- \list
- \li Image.Stretch - the image is scaled to fit
- \li Image.PreserveAspectFit - the image is scaled uniformly to fit without cropping
- \li Image.PreserveAspectCrop - the image is scaled uniformly to fill, cropping if necessary
- \li Image.Tile - the image is duplicated horizontally and vertically
- \li Image.TileVertically - the image is stretched horizontally and tiled vertically
- \li Image.TileHorizontally - the image is stretched vertically and tiled horizontally
- \li Image.Pad - the image is not transformed
- \endlist
+
+ \value Image.Stretch the image is scaled to fit
+ \value Image.PreserveAspectFit the image is scaled uniformly to fit without cropping
+ \value Image.PreserveAspectCrop the image is scaled uniformly to fill, cropping if necessary
+ \value Image.Tile the image is duplicated horizontally and vertically
+ \value Image.TileVertically the image is stretched horizontally and tiled vertically
+ \value Image.TileHorizontally the image is stretched vertically and tiled horizontally
+ \value Image.Pad the image is not transformed
+ \br
\table
@@ -362,9 +352,9 @@ void QQuickImage::setFillMode(FillMode mode)
}
/*!
-
\qmlproperty real QtQuick::Image::paintedWidth
\qmlproperty real QtQuick::Image::paintedHeight
+ \readonly
These properties hold the size of the image that is actually painted.
In most cases it is the same as \c width and \c height, but when using an
@@ -386,14 +376,14 @@ qreal QQuickImage::paintedHeight() const
/*!
\qmlproperty enumeration QtQuick::Image::status
+ \readonly
This property holds the status of image loading. It can be one of:
- \list
- \li Image.Null - no image has been set
- \li Image.Ready - the image has been loaded
- \li Image.Loading - the image is currently being loaded
- \li Image.Error - an error occurred while loading the image
- \endlist
+
+ \value Image.Null No image has been set
+ \value Image.Ready The image has been loaded
+ \value Image.Loading The image is currently being loaded
+ \value Image.Error An error occurred while loading the image
Use this status to provide an update or respond to the status change in some way.
For example, you could:
@@ -423,6 +413,7 @@ qreal QQuickImage::paintedHeight() const
/*!
\qmlproperty real QtQuick::Image::progress
+ \readonly
This property holds the progress of image loading, from 0.0 (nothing loaded)
to 1.0 (finished).
@@ -444,12 +435,12 @@ qreal QQuickImage::paintedHeight() const
*/
/*!
- \qmlproperty QSize QtQuick::Image::sourceSize
+ \qmlproperty size QtQuick::Image::sourceSize
- This property holds the actual width and height of the loaded image.
+ This property holds the scaled width and height of the full-frame image.
Unlike the \l {Item::}{width} and \l {Item::}{height} properties, which scale
- the painting of the image, this property sets the actual number of pixels
+ the painting of the image, this property sets the maximum number of pixels
stored for the loaded image so that large images do not use more
memory than necessary. For example, this ensures the image in memory is no
larger than 1024x1024 pixels, regardless of the Image's \l {Item::}{width} and
@@ -474,7 +465,7 @@ 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
+ If both the sourceSize.width and sourceSize.height are set, the image will be scaled
down to fit within the specified size (unless PreserveAspectCrop or PreserveAspectFit
are used, then it will be scaled to match the optimal size for cropping/fitting),
maintaining the image's aspect ratio. The actual
@@ -489,11 +480,61 @@ 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.
+ If the \l sourceClipRect property is also set, \c sourceSize determines the scale,
+ but it will be clipped to the size of the clip rectangle.
+
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,
potentially even from the network, if it is not in the disk cache.}
+
+ \sa {Qt Quick Examples - Pointer Handlers}
+*/
+
+/*!
+ \qmlproperty rect QtQuick::Image::sourceClipRect
+ \since 5.15
+
+ This property, if set, holds the rectangular region of the source image to
+ be loaded.
+
+ The \c sourceClipRect works together with the \l sourceSize property to
+ conserve system resources when only a portion of an image needs to be
+ loaded.
+
+ \code
+ Rectangle {
+ width: ...
+ height: ...
+
+ Image {
+ anchors.fill: parent
+ source: "reallyBigImage.svg"
+ sourceSize.width: 1024
+ sourceSize.height: 1024
+ sourceClipRect: Qt.rect(100, 100, 512, 512)
+ }
+ }
+ \endcode
+
+ In the above example, we conceptually scale the SVG graphic to 1024x1024
+ first, and then cut out a region of interest that is 512x512 pixels from a
+ location 100 pixels from the top and left edges. Thus \c sourceSize
+ determines the scale, but the actual output image is 512x512 pixels.
+
+ Some image formats are able to conserve CPU time by rendering only the
+ specified region. Others will need to load the entire image first and then
+ clip it to the specified region.
+
+ This property can be cleared to reload the entire image by setting
+ \c sourceClipRect to \c undefined.
+
+ \note \e {Changing this property dynamically causes the image source to be reloaded,
+ potentially even from the network, if it is not in the disk cache.}
+
+ \note Sub-pixel clipping is not supported: the given rectangle will be
+ passed to \l QImageReader::setScaledClipRect().
*/
/*!
@@ -503,7 +544,7 @@ qreal QQuickImage::paintedHeight() const
The URL may be absolute, or relative to the URL of the component.
- \sa QQuickImageProvider {OpenGL Texture Files} {Automatic Detection of File Extension}
+ \sa QQuickImageProvider, {Compressed Texture Files}, {Automatic Detection of File Extension}
*/
/*!
@@ -539,6 +580,17 @@ qreal QQuickImage::paintedHeight() const
*/
/*!
+ \qmlproperty bool QtQuick::Image::mirrorVertically
+
+ This property holds whether the image should be vertically inverted
+ (effectively displaying a mirrored image).
+
+ The default value is false.
+
+ \since 6.2
+*/
+
+/*!
\qmlproperty enumeration QtQuick::Image::horizontalAlignment
\qmlproperty enumeration QtQuick::Image::verticalAlignment
@@ -553,12 +605,12 @@ void QQuickImage::updatePaintedGeometry()
Q_D(QQuickImage);
if (d->fillMode == PreserveAspectFit) {
- if (!d->pix.width() || !d->pix.height()) {
+ if (!d->currentPix->width() || !d->currentPix->height()) {
setImplicitSize(0, 0);
return;
}
- const qreal pixWidth = d->pix.width() / d->devicePixelRatio;
- const qreal pixHeight = d->pix.height() / d->devicePixelRatio;
+ const qreal pixWidth = d->currentPix->width() / d->devicePixelRatio;
+ const qreal pixHeight = d->currentPix->height() / d->devicePixelRatio;
const qreal w = widthValid() ? width() : pixWidth;
const qreal widthScale = w / pixWidth;
const qreal h = heightValid() ? height() : pixHeight;
@@ -575,10 +627,10 @@ void QQuickImage::updatePaintedGeometry()
setImplicitSize(iWidth, iHeight);
} else if (d->fillMode == PreserveAspectCrop) {
- if (!d->pix.width() || !d->pix.height())
+ if (!d->currentPix->width() || !d->currentPix->height())
return;
- const qreal pixWidth = d->pix.width() / d->devicePixelRatio;
- const qreal pixHeight = d->pix.height() / d->devicePixelRatio;
+ const qreal pixWidth = d->currentPix->width() / d->devicePixelRatio;
+ const qreal pixHeight = d->currentPix->height() / d->devicePixelRatio;
qreal widthScale = width() / pixWidth;
qreal heightScale = height() / pixHeight;
if (widthScale < heightScale) {
@@ -590,8 +642,8 @@ void QQuickImage::updatePaintedGeometry()
d->paintedHeight = heightScale * pixHeight;
d->paintedWidth = widthScale * pixWidth;
} else if (d->fillMode == Pad) {
- d->paintedWidth = d->pix.width() / d->devicePixelRatio;
- d->paintedHeight = d->pix.height() / d->devicePixelRatio;
+ d->paintedWidth = d->currentPix->width() / d->devicePixelRatio;
+ d->paintedHeight = d->currentPix->height() / d->devicePixelRatio;
} else {
d->paintedWidth = width();
d->paintedHeight = height();
@@ -599,9 +651,9 @@ void QQuickImage::updatePaintedGeometry()
emit paintedGeometryChanged();
}
-void QQuickImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void QQuickImage::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
- QQuickImageBase::geometryChanged(newGeometry, oldGeometry);
+ QQuickImageBase::geometryChange(newGeometry, oldGeometry);
if (newGeometry.size() != oldGeometry.size())
updatePaintedGeometry();
}
@@ -633,7 +685,7 @@ QSGTextureProvider *QQuickImage::textureProvider() const
dd->provider = new QQuickImageTextureProvider;
dd->provider->m_smooth = d->smooth;
dd->provider->m_mipmap = d->mipmap;
- dd->provider->updateTexture(d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window()));
+ dd->provider->updateTexture(d->sceneGraphRenderContext()->textureForFactory(d->currentPix->textureFactory(), window()));
}
return d->provider;
@@ -659,7 +711,7 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
Q_D(QQuickImage);
- QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window());
+ QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->currentPix->textureFactory(), window());
// Copy over the current texture state into the texture provider...
if (d->provider) {
@@ -676,7 +728,7 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
QSGInternalImageNode *node = static_cast<QSGInternalImageNode *>(oldNode);
if (!node) {
d->pixmapChanged = true;
- node = d->sceneGraphContext()->createInternalImageNode();
+ node = d->sceneGraphContext()->createInternalImageNode(d->sceneGraphRenderContext());
}
QRectF targetRect;
@@ -684,55 +736,54 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
QSGTexture::WrapMode hWrap = QSGTexture::ClampToEdge;
QSGTexture::WrapMode vWrap = QSGTexture::ClampToEdge;
- qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->pix.width() / d->devicePixelRatio;
- qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->pix.height() / d->devicePixelRatio;
+ qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->currentPix->width() / d->devicePixelRatio;
+ qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->currentPix->height() / d->devicePixelRatio;
int xOffset = 0;
if (d->hAlign == QQuickImage::AlignHCenter)
- xOffset = qCeil((width() - pixWidth) / 2.);
+ xOffset = (width() - pixWidth) / 2;
else if (d->hAlign == QQuickImage::AlignRight)
xOffset = qCeil(width() - pixWidth);
int yOffset = 0;
if (d->vAlign == QQuickImage::AlignVCenter)
- yOffset = qCeil((height() - pixHeight) / 2.);
+ yOffset = (height() - pixHeight) / 2;
else if (d->vAlign == QQuickImage::AlignBottom)
yOffset = qCeil(height() - pixHeight);
switch (d->fillMode) {
- default:
case Stretch:
targetRect = QRectF(0, 0, width(), height());
- sourceRect = d->pix.rect();
+ sourceRect = d->currentPix->rect();
break;
case PreserveAspectFit:
targetRect = QRectF(xOffset, yOffset, d->paintedWidth, d->paintedHeight);
- sourceRect = d->pix.rect();
+ sourceRect = d->currentPix->rect();
break;
case PreserveAspectCrop: {
- targetRect = QRect(0, 0, width(), height());
- qreal wscale = width() / qreal(d->pix.width());
- qreal hscale = height() / qreal(d->pix.height());
+ targetRect = QRectF(0, 0, width(), height());
+ qreal wscale = width() / qreal(d->currentPix->width());
+ qreal hscale = height() / qreal(d->currentPix->height());
if (wscale > hscale) {
- int src = (hscale / wscale) * qreal(d->pix.height());
+ int src = (hscale / wscale) * qreal(d->currentPix->height());
int y = 0;
if (d->vAlign == QQuickImage::AlignVCenter)
- y = qCeil((d->pix.height() - src) / 2.);
+ y = qCeil((d->currentPix->height() - src) / 2.);
else if (d->vAlign == QQuickImage::AlignBottom)
- y = qCeil(d->pix.height() - src);
- sourceRect = QRectF(0, y, d->pix.width(), src);
+ y = qCeil(d->currentPix->height() - src);
+ sourceRect = QRectF(0, y, d->currentPix->width(), src);
} else {
- int src = (wscale / hscale) * qreal(d->pix.width());
+ int src = (wscale / hscale) * qreal(d->currentPix->width());
int x = 0;
if (d->hAlign == QQuickImage::AlignHCenter)
- x = qCeil((d->pix.width() - src) / 2.);
+ x = qCeil((d->currentPix->width() - src) / 2.);
else if (d->hAlign == QQuickImage::AlignRight)
- x = qCeil(d->pix.width() - src);
- sourceRect = QRectF(x, 0, src, d->pix.height());
+ x = qCeil(d->currentPix->width() - src);
+ sourceRect = QRectF(x, 0, src, d->currentPix->height());
}
}
break;
@@ -746,13 +797,13 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
case TileHorizontally:
targetRect = QRectF(0, 0, width(), height());
- sourceRect = QRectF(-xOffset, 0, width(), d->pix.height());
+ sourceRect = QRectF(-xOffset, 0, width(), d->currentPix->height());
hWrap = QSGTexture::Repeat;
break;
case TileVertically:
targetRect = QRectF(0, 0, width(), height());
- sourceRect = QRectF(0, -yOffset, d->pix.width(), height());
+ sourceRect = QRectF(0, -yOffset, d->currentPix->width(), height());
vWrap = QSGTexture::Repeat;
break;
@@ -764,10 +815,10 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
targetRect = QRectF(x + xOffset, y + yOffset, w, h);
sourceRect = QRectF(x, y, w, h);
break;
- };
+ }
- qreal nsWidth = (hWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->pix.width() / d->devicePixelRatio : d->pix.width();
- qreal nsHeight = (vWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->pix.height() / d->devicePixelRatio : d->pix.height();
+ qreal nsWidth = (hWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->currentPix->width() / d->devicePixelRatio : d->currentPix->width();
+ qreal nsHeight = (vWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->currentPix->height() / d->devicePixelRatio : d->currentPix->height();
QRectF nsrect(sourceRect.x() / nsWidth,
sourceRect.y() / nsHeight,
sourceRect.width() / nsWidth,
@@ -799,7 +850,7 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
node->setTargetRect(targetRect);
node->setInnerTargetRect(targetRect);
node->setSubSourceRect(nsrect);
- node->setMirror(d->mirror);
+ node->setMirror(d->mirrorHorizontally, d->mirrorVertically);
node->setAntialiasing(d->antialiasing);
node->update();
@@ -889,6 +940,8 @@ void QQuickImage::setMipmap(bool use)
emit mipmapChanged(d->mipmap);
d->pixmapChanged = true;
+ if (isComponentComplete())
+ load();
update();
}
@@ -902,4 +955,39 @@ void QQuickImage::setMipmap(bool use)
By default, this property is set to false.
*/
+/*!
+ \qmlproperty int QtQuick::Image::currentFrame
+ \qmlproperty int QtQuick::Image::frameCount
+ \since 5.14
+
+ currentFrame is the frame that is currently visible. The default is \c 0.
+ You can set it to a number between \c 0 and \c {frameCount - 1} to display a
+ different frame, if the image contains multiple frames.
+
+ frameCount is the number of frames in the image. Most images have only one frame.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::Image::retainWhileLoading
+ \since 6.8
+
+//! [qml-image-retainwhileloading]
+ This property defines the behavior when the \l source property is changed and loading happens
+ asynchronously. This is the case when the \l asynchronous property is set to \c true, or if the
+ image is not on the local file system.
+
+ If \c retainWhileLoading is \c false (the default), the old image is discarded immediately, and
+ the component is cleared while the new image is being loaded. If set to \c true, the old image
+ is retained and remains visible until the new one is ready.
+
+ Enabling this property can avoid flickering in cases where loading the new image takes a long
+ time. It comes at the cost of some extra memory use for double buffering while the new image is
+ being loaded.
+//! [qml-image-retainwhileloading]
+ */
+
QT_END_NAMESPACE
+
+#include "moc_qquickimage_p_p.cpp"
+
+#include "moc_qquickimage_p.cpp"