File indexing completed on 2025-07-13 03:38:12
0001 /* 0002 SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org> 0003 SPDX-FileCopyrightText: 2015 Luca Beltrame <lbeltrame@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "qimageitem.h" 0009 0010 #include <QPainter> 0011 0012 QImageItem::QImageItem(QQuickItem *parent) 0013 : QQuickPaintedItem(parent) 0014 , m_fillMode(QImageItem::Stretch) 0015 { 0016 setFlag(ItemHasContents, true); 0017 } 0018 0019 QImageItem::~QImageItem() 0020 { 0021 } 0022 0023 void QImageItem::setImage(const QImage &image) 0024 { 0025 bool oldImageNull = m_image.isNull(); 0026 m_image = image; 0027 updatePaintedRect(); 0028 update(); 0029 Q_EMIT nativeWidthChanged(); 0030 Q_EMIT nativeHeightChanged(); 0031 Q_EMIT imageChanged(); 0032 if (oldImageNull != m_image.isNull()) { 0033 Q_EMIT nullChanged(); 0034 } 0035 } 0036 0037 QImage QImageItem::image() const 0038 { 0039 return m_image; 0040 } 0041 0042 void QImageItem::resetImage() 0043 { 0044 setImage(QImage()); 0045 } 0046 0047 int QImageItem::nativeWidth() const 0048 { 0049 return m_image.size().width() / m_image.devicePixelRatio(); 0050 } 0051 0052 int QImageItem::nativeHeight() const 0053 { 0054 return m_image.size().height() / m_image.devicePixelRatio(); 0055 } 0056 0057 QImageItem::FillMode QImageItem::fillMode() const 0058 { 0059 return m_fillMode; 0060 } 0061 0062 void QImageItem::setFillMode(QImageItem::FillMode mode) 0063 { 0064 if (mode == m_fillMode) { 0065 return; 0066 } 0067 0068 m_fillMode = mode; 0069 updatePaintedRect(); 0070 update(); 0071 Q_EMIT fillModeChanged(); 0072 } 0073 0074 void QImageItem::paint(QPainter *painter) 0075 { 0076 if (m_image.isNull()) { 0077 return; 0078 } 0079 painter->save(); 0080 painter->setRenderHint(QPainter::Antialiasing, smooth()); 0081 painter->setRenderHint(QPainter::SmoothPixmapTransform, smooth()); 0082 0083 if (m_fillMode == TileVertically) { 0084 painter->scale(width() / (qreal)m_image.width(), 1); 0085 } 0086 0087 if (m_fillMode == TileHorizontally) { 0088 painter->scale(1, height() / (qreal)m_image.height()); 0089 } 0090 0091 if (m_fillMode == Pad) { 0092 QRect centeredRect = m_paintedRect; 0093 centeredRect.moveCenter(m_image.rect().center()); 0094 painter->drawImage(m_paintedRect, m_image, centeredRect); 0095 } else if (m_fillMode >= Tile) { 0096 painter->drawTiledPixmap(m_paintedRect, QPixmap::fromImage(m_image)); 0097 } else { 0098 painter->drawImage(m_paintedRect, m_image, m_image.rect()); 0099 } 0100 0101 painter->restore(); 0102 } 0103 0104 bool QImageItem::isNull() const 0105 { 0106 return m_image.isNull(); 0107 } 0108 0109 int QImageItem::paintedWidth() const 0110 { 0111 if (m_image.isNull()) { 0112 return 0; 0113 } 0114 0115 return m_paintedRect.width(); 0116 } 0117 0118 int QImageItem::paintedHeight() const 0119 { 0120 if (m_image.isNull()) { 0121 return 0; 0122 } 0123 0124 return m_paintedRect.height(); 0125 } 0126 0127 void QImageItem::updatePaintedRect() 0128 { 0129 if (m_image.isNull()) { 0130 return; 0131 } 0132 0133 QRectF sourceRect = m_paintedRect; 0134 0135 QRectF destRect; 0136 0137 switch (m_fillMode) { 0138 case PreserveAspectFit: { 0139 QSizeF scaled = m_image.size(); 0140 0141 scaled.scale(boundingRect().size(), Qt::KeepAspectRatio); 0142 destRect = QRectF(QPoint(0, 0), scaled); 0143 destRect.moveCenter(boundingRect().center().toPoint()); 0144 break; 0145 } 0146 case PreserveAspectCrop: { 0147 QSizeF scaled = m_image.size(); 0148 0149 scaled.scale(boundingRect().size(), Qt::KeepAspectRatioByExpanding); 0150 destRect = QRectF(QPoint(0, 0), scaled); 0151 destRect.moveCenter(boundingRect().center().toPoint()); 0152 break; 0153 } 0154 case TileVertically: { 0155 destRect = boundingRect().toRect(); 0156 destRect.setWidth(destRect.width() / (width() / (qreal)m_image.width())); 0157 break; 0158 } 0159 case TileHorizontally: { 0160 destRect = boundingRect().toRect(); 0161 destRect.setHeight(destRect.height() / (height() / (qreal)m_image.height())); 0162 break; 0163 } 0164 case Stretch: 0165 case Tile: 0166 case Pad: 0167 default: 0168 destRect = boundingRect().toRect(); 0169 } 0170 0171 if (destRect != sourceRect) { 0172 m_paintedRect = destRect.toRect(); 0173 Q_EMIT paintedHeightChanged(); 0174 Q_EMIT paintedWidthChanged(); 0175 } 0176 } 0177 void QImageItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) 0178 { 0179 QQuickPaintedItem::geometryChange(newGeometry, oldGeometry); 0180 updatePaintedRect(); 0181 } 0182 0183 #include "moc_qimageitem.cpp"