620void QQuickImage::updatePaintedGeometry()
624 if (d->fillMode == PreserveAspectFit) {
625 if (!d->currentPix->width() || !d->currentPix->height()) {
626 setImplicitSize(0, 0);
629 const qreal pixWidth = d->currentPix->width() / d->devicePixelRatio;
630 const qreal pixHeight = d->currentPix->height() / d->devicePixelRatio;
631 const qreal w = widthValid() ? width() : pixWidth;
632 const qreal widthScale = w / pixWidth;
633 const qreal h = heightValid() ? height() : pixHeight;
634 const qreal heightScale = h / pixHeight;
635 if (widthScale <= heightScale) {
637 d->paintedHeight = widthScale * pixHeight;
638 }
else if (heightScale < widthScale) {
639 d->paintedWidth = heightScale * pixWidth;
640 d->paintedHeight = h;
642 const qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : pixHeight;
643 const qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : pixWidth;
644 setImplicitSize(iWidth, iHeight);
646 }
else if (d->fillMode == PreserveAspectCrop) {
647 if (!d->currentPix->width() || !d->currentPix->height())
649 const qreal pixWidth = d->currentPix->width() / d->devicePixelRatio;
650 const qreal pixHeight = d->currentPix->height() / d->devicePixelRatio;
651 qreal widthScale = width() / pixWidth;
652 qreal heightScale = height() / pixHeight;
653 if (widthScale < heightScale) {
654 widthScale = heightScale;
655 }
else if (heightScale < widthScale) {
656 heightScale = widthScale;
659 d->paintedHeight = heightScale * pixHeight;
660 d->paintedWidth = widthScale * pixWidth;
661 }
else if (d->fillMode == Pad) {
662 d->paintedWidth = d->currentPix->width() / d->devicePixelRatio;
663 d->paintedHeight = d->currentPix->height() / d->devicePixelRatio;
665 d->paintedWidth = width();
666 d->paintedHeight = height();
668 emit paintedGeometryChanged();
730QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
734 QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->currentPix->textureFactory(), window());
736 reloadIfTransientImageDropped();
740 d->provider->m_smooth = d->smooth;
741 d->provider->m_mipmap = d->mipmap;
742 d->provider->updateTexture(texture);
745 if (!texture || width() <= 0 || height() <= 0) {
750 QSGInternalImageNode *node =
static_cast<QSGInternalImageNode *>(oldNode);
752 d->pixmapChanged =
true;
753 node = d->sceneGraphContext()->createInternalImageNode(d->sceneGraphRenderContext());
758 QSGTexture::WrapMode hWrap = QSGTexture::ClampToEdge;
759 QSGTexture::WrapMode vWrap = QSGTexture::ClampToEdge;
761 qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->currentPix->width() / d->devicePixelRatio;
762 qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->currentPix->height() / d->devicePixelRatio;
765 if (d->hAlign == QQuickImage::AlignHCenter)
766 xOffset = (width() - pixWidth) / 2;
767 else if (d->hAlign == QQuickImage::AlignRight)
768 xOffset = qCeil(width() - pixWidth);
771 if (d->vAlign == QQuickImage::AlignVCenter)
772 yOffset = (height() - pixHeight) / 2;
773 else if (d->vAlign == QQuickImage::AlignBottom)
774 yOffset = qCeil(height() - pixHeight);
776 switch (d->fillMode) {
778 targetRect = QRectF(0, 0, width(), height());
779 sourceRect = d->currentPix->rect();
782 case PreserveAspectFit:
783 targetRect = QRectF(xOffset, yOffset, d->paintedWidth, d->paintedHeight);
784 sourceRect = d->currentPix->rect();
787 case PreserveAspectCrop: {
788 targetRect = QRectF(0, 0, width(), height());
789 qreal wscale = width() / qreal(d->currentPix->width());
790 qreal hscale = height() / qreal(d->currentPix->height());
792 if (wscale > hscale) {
793 int src = (hscale / wscale) * qreal(d->currentPix->height());
795 if (d->vAlign == QQuickImage::AlignVCenter)
796 y = qCeil((d->currentPix->height() - src) / 2.);
797 else if (d->vAlign == QQuickImage::AlignBottom)
798 y = qCeil(d->currentPix->height() - src);
799 sourceRect = QRectF(0, y, d->currentPix->width(), src);
802 int src = (wscale / hscale) * qreal(d->currentPix->width());
804 if (d->hAlign == QQuickImage::AlignHCenter)
805 x = qCeil((d->currentPix->width() - src) / 2.);
806 else if (d->hAlign == QQuickImage::AlignRight)
807 x = qCeil(d->currentPix->width() - src);
808 sourceRect = QRectF(x, 0, src, d->currentPix->height());
814 targetRect = QRectF(0, 0, width(), height());
815 sourceRect = QRectF(-xOffset, -yOffset, width(), height());
816 hWrap = QSGTexture::Repeat;
817 vWrap = QSGTexture::Repeat;
820 case TileHorizontally:
821 targetRect = QRectF(0, 0, width(), height());
822 sourceRect = QRectF(-xOffset, 0, width(), d->currentPix->height());
823 hWrap = QSGTexture::Repeat;
827 targetRect = QRectF(0, 0, width(), height());
828 sourceRect = QRectF(0, -yOffset, d->currentPix->width(), height());
829 vWrap = QSGTexture::Repeat;
833 qreal w = qMin(qreal(pixWidth), width());
834 qreal h = qMin(qreal(pixHeight), height());
835 qreal x = (pixWidth > width()) ? -xOffset : 0;
836 qreal y = (pixHeight > height()) ? -yOffset : 0;
837 targetRect = QRectF(x + xOffset, y + yOffset, w, h);
838 sourceRect = QRectF(x, y, w, h);
842 qreal nsWidth = (hWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->currentPix->width() / d->devicePixelRatio : d->currentPix->width();
843 qreal nsHeight = (vWrap == QSGTexture::Repeat || d->fillMode == Pad) ? d->currentPix->height() / d->devicePixelRatio : d->currentPix->height();
844 QRectF nsrect(sourceRect.x() / nsWidth,
845 sourceRect.y() / nsHeight,
846 sourceRect.width() / nsWidth,
847 sourceRect.height() / nsHeight);
849 if (targetRect.isEmpty()
850 || !qt_is_finite(targetRect.width()) || !qt_is_finite(targetRect.height())
852 || !qt_is_finite(nsrect.width()) || !qt_is_finite(nsrect.height())) {
857 if (d->pixmapChanged) {
860 if (texture->isAtlasTexture() && (hWrap == QSGTexture::Repeat || vWrap == QSGTexture::Repeat || d->mipmap))
861 node->setTexture(texture->removedFromAtlas());
863 node->setTexture(texture);
864 d->pixmapChanged =
false;
867 node->setMipmapFiltering(d->mipmap ? QSGTexture::Linear : QSGTexture::None);
868 node->setHorizontalWrapMode(hWrap);
869 node->setVerticalWrapMode(vWrap);
870 node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
872 node->setTargetRect(targetRect);
873 node->setInnerTargetRect(targetRect);
874 node->setSubSourceRect(nsrect);
875 node->setMirror(d->mirrorHorizontally, d->mirrorVertically);
876 node->setAntialiasing(d->antialiasing);