614void QQuickImage::updatePaintedGeometry()
618 if (d->fillMode == PreserveAspectFit) {
619 if (!d->currentPix->width() || !d->currentPix->height()) {
620 setImplicitSize(0, 0);
623 const qreal pixWidth = d->currentPix->width() / d->devicePixelRatio;
624 const qreal pixHeight = d->currentPix->height() / d->devicePixelRatio;
625 const qreal w = widthValid() ? width() : pixWidth;
626 const qreal widthScale = w / pixWidth;
627 const qreal h = heightValid() ? height() : pixHeight;
628 const qreal heightScale = h / pixHeight;
629 if (widthScale <= heightScale) {
631 d->paintedHeight = widthScale * pixHeight;
632 }
else if (heightScale < widthScale) {
633 d->paintedWidth = heightScale * pixWidth;
634 d->paintedHeight = h;
636 const qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : pixHeight;
637 const qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : pixWidth;
638 setImplicitSize(iWidth, iHeight);
640 }
else if (d->fillMode == PreserveAspectCrop) {
641 if (!d->currentPix->width() || !d->currentPix->height())
643 const qreal pixWidth = d->currentPix->width() / d->devicePixelRatio;
644 const qreal pixHeight = d->currentPix->height() / d->devicePixelRatio;
645 qreal widthScale = width() / pixWidth;
646 qreal heightScale = height() / pixHeight;
647 if (widthScale < heightScale) {
648 widthScale = heightScale;
649 }
else if (heightScale < widthScale) {
650 heightScale = widthScale;
653 d->paintedHeight = heightScale * pixHeight;
654 d->paintedWidth = widthScale * pixWidth;
655 }
else if (d->fillMode == Pad) {
656 d->paintedWidth = d->currentPix->width() / d->devicePixelRatio;
657 d->paintedHeight = d->currentPix->height() / d->devicePixelRatio;
659 d->paintedWidth = width();
660 d->paintedHeight = height();
662 emit paintedGeometryChanged();
721QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
725 QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->currentPix->textureFactory(), window());
729 d->provider->m_smooth = d->smooth;
730 d->provider->m_mipmap = d->mipmap;
731 d->provider->updateTexture(texture);
734 if (!texture || width() <= 0 || height() <= 0) {
739 QSGInternalImageNode *node =
static_cast<QSGInternalImageNode *>(oldNode);
741 d->pixmapChanged =
true;
742 node = d->sceneGraphContext()->createInternalImageNode(d->sceneGraphRenderContext());
747 QSGTexture::WrapMode hWrap = QSGTexture::ClampToEdge;
748 QSGTexture::WrapMode vWrap = QSGTexture::ClampToEdge;
750 qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->currentPix->width() / d->devicePixelRatio;
751 qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->currentPix->height() / d->devicePixelRatio;
754 if (d->hAlign == QQuickImage::AlignHCenter)
755 xOffset = (width() - pixWidth) / 2;
756 else if (d->hAlign == QQuickImage::AlignRight)
757 xOffset = qCeil(width() - pixWidth);
760 if (d->vAlign == QQuickImage::AlignVCenter)
761 yOffset = (height() - pixHeight) / 2;
762 else if (d->vAlign == QQuickImage::AlignBottom)
763 yOffset = qCeil(height() - pixHeight);
765 switch (d->fillMode) {
767 targetRect = QRectF(0, 0, width(), height());
768 sourceRect = d->currentPix->rect();
771 case PreserveAspectFit:
772 targetRect = QRectF(xOffset, yOffset, d->paintedWidth, d->paintedHeight);
773 sourceRect = d->currentPix->rect();
776 case PreserveAspectCrop: {
777 targetRect = QRectF(0, 0, width(), height());
778 qreal wscale = width() / qreal(d->currentPix->width());
779 qreal hscale = height() / qreal(d->currentPix->height());
781 if (wscale > hscale) {
782 int src = (hscale / wscale) * qreal(d->currentPix->height());
784 if (d->vAlign == QQuickImage::AlignVCenter)
785 y = qCeil((d->currentPix->height() - src) / 2.);
786 else if (d->vAlign == QQuickImage::AlignBottom)
787 y = qCeil(d->currentPix->height() - src);
788 sourceRect = QRectF(0, y, d->currentPix->width(), src);
791 int src = (wscale / hscale) * qreal(d->currentPix->width());
793 if (d->hAlign == QQuickImage::AlignHCenter)
794 x = qCeil((d->currentPix->width() - src) / 2.);
795 else if (d->hAlign == QQuickImage::AlignRight)
796 x = qCeil(d->currentPix->width() - src);
797 sourceRect = QRectF(x, 0, src, d->currentPix->height());
803 targetRect = QRectF(0, 0, width(), height());
804 sourceRect = QRectF(-xOffset, -yOffset, width(), height());
805 hWrap = QSGTexture::Repeat;
806 vWrap = QSGTexture::Repeat;
809 case TileHorizontally:
810 targetRect = QRectF(0, 0, width(), height());
811 sourceRect = QRectF(-xOffset, 0, width(), d->currentPix->height());
812 hWrap = QSGTexture::Repeat;
816 targetRect = QRectF(0, 0, width(), height());
817 sourceRect = QRectF(0, -yOffset, d->currentPix->width(), height());
818 vWrap = QSGTexture::Repeat;
822 qreal w = qMin(qreal(pixWidth), width());
823 qreal h = qMin(qreal(pixHeight), height());
824 qreal x = (pixWidth > width()) ? -xOffset : 0;
825 qreal y = (pixHeight > height()) ? -yOffset : 0;
826 targetRect = QRectF(x + xOffset, y + yOffset, w, h);
827 sourceRect = QRectF(x, y, w, h);
831 qreal nsWidth = (hWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->currentPix->width() / d->devicePixelRatio : d->currentPix->width();
832 qreal nsHeight = (vWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->currentPix->height() / d->devicePixelRatio : d->currentPix->height();
833 QRectF nsrect(sourceRect.x() / nsWidth,
834 sourceRect.y() / nsHeight,
835 sourceRect.width() / nsWidth,
836 sourceRect.height() / nsHeight);
838 if (targetRect.isEmpty()
839 || !qt_is_finite(targetRect.width()) || !qt_is_finite(targetRect.height())
841 || !qt_is_finite(nsrect.width()) || !qt_is_finite(nsrect.height())) {
846 if (d->pixmapChanged) {
849 if (texture->isAtlasTexture() && (hWrap == QSGTexture::Repeat || vWrap == QSGTexture::Repeat || d->mipmap))
850 node->setTexture(texture->removedFromAtlas());
852 node->setTexture(texture);
853 d->pixmapChanged =
false;
856 node->setMipmapFiltering(d->mipmap ? QSGTexture::Linear : QSGTexture::None);
857 node->setHorizontalWrapMode(hWrap);
858 node->setVerticalWrapMode(vWrap);
859 node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
861 node->setTargetRect(targetRect);
862 node->setInnerTargetRect(targetRect);
863 node->setSubSourceRect(nsrect);
864 node->setMirror(d->mirrorHorizontally, d->mirrorVertically);
865 node->setAntialiasing(d->antialiasing);