File indexing completed on 2024-05-19 15:09:25
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_smooth(false) 0015 , m_fillMode(QImageItem::Stretch) 0016 { 0017 setFlag(ItemHasContents, true); 0018 } 0019 0020 QImageItem::~QImageItem() 0021 { 0022 } 0023 0024 void QImageItem::setImage(const QImage &image) 0025 { 0026 bool oldImageNull = m_image.isNull(); 0027 m_image = image; 0028 updatePaintedRect(); 0029 update(); 0030 Q_EMIT nativeWidthChanged(); 0031 Q_EMIT nativeHeightChanged(); 0032 Q_EMIT imageChanged(); 0033 if (oldImageNull != m_image.isNull()) { 0034 Q_EMIT nullChanged(); 0035 } 0036 } 0037 0038 QImage QImageItem::image() const 0039 { 0040 return m_image; 0041 } 0042 0043 void QImageItem::resetImage() 0044 { 0045 setImage(QImage()); 0046 } 0047 0048 void QImageItem::setSmooth(const bool smooth) 0049 { 0050 if (smooth == m_smooth) { 0051 return; 0052 } 0053 m_smooth = smooth; 0054 update(); 0055 } 0056 0057 bool QImageItem::smooth() const 0058 { 0059 return m_smooth; 0060 } 0061 0062 int QImageItem::nativeWidth() const 0063 { 0064 return m_image.size().width() / m_image.devicePixelRatio(); 0065 } 0066 0067 int QImageItem::nativeHeight() const 0068 { 0069 return m_image.size().height() / m_image.devicePixelRatio(); 0070 } 0071 0072 QImageItem::FillMode QImageItem::fillMode() const 0073 { 0074 return m_fillMode; 0075 } 0076 0077 void QImageItem::setFillMode(QImageItem::FillMode mode) 0078 { 0079 if (mode == m_fillMode) { 0080 return; 0081 } 0082 0083 m_fillMode = mode; 0084 updatePaintedRect(); 0085 update(); 0086 Q_EMIT fillModeChanged(); 0087 } 0088 0089 void QImageItem::paint(QPainter *painter) 0090 { 0091 if (m_image.isNull()) { 0092 return; 0093 } 0094 painter->save(); 0095 painter->setRenderHint(QPainter::Antialiasing, m_smooth); 0096 painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); 0097 0098 if (m_fillMode == TileVertically) { 0099 painter->scale(width() / (qreal)m_image.width(), 1); 0100 } 0101 0102 if (m_fillMode == TileHorizontally) { 0103 painter->scale(1, height() / (qreal)m_image.height()); 0104 } 0105 0106 if (m_fillMode == Pad) { 0107 QRect centeredRect = m_paintedRect; 0108 centeredRect.moveCenter(m_image.rect().center()); 0109 painter->drawImage(m_paintedRect, m_image, centeredRect); 0110 } else if (m_fillMode >= Tile) { 0111 painter->drawTiledPixmap(m_paintedRect, QPixmap::fromImage(m_image)); 0112 } else { 0113 painter->drawImage(m_paintedRect, m_image, m_image.rect()); 0114 } 0115 0116 painter->restore(); 0117 } 0118 0119 bool QImageItem::isNull() const 0120 { 0121 return m_image.isNull(); 0122 } 0123 0124 int QImageItem::paintedWidth() const 0125 { 0126 if (m_image.isNull()) { 0127 return 0; 0128 } 0129 0130 return m_paintedRect.width(); 0131 } 0132 0133 int QImageItem::paintedHeight() const 0134 { 0135 if (m_image.isNull()) { 0136 return 0; 0137 } 0138 0139 return m_paintedRect.height(); 0140 } 0141 0142 void QImageItem::updatePaintedRect() 0143 { 0144 if (m_image.isNull()) { 0145 return; 0146 } 0147 0148 QRectF sourceRect = m_paintedRect; 0149 0150 QRectF destRect; 0151 0152 switch (m_fillMode) { 0153 case PreserveAspectFit: { 0154 QSizeF scaled = m_image.size(); 0155 0156 scaled.scale(boundingRect().size(), Qt::KeepAspectRatio); 0157 destRect = QRectF(QPoint(0, 0), scaled); 0158 destRect.moveCenter(boundingRect().center().toPoint()); 0159 break; 0160 } 0161 case PreserveAspectCrop: { 0162 QSizeF scaled = m_image.size(); 0163 0164 scaled.scale(boundingRect().size(), Qt::KeepAspectRatioByExpanding); 0165 destRect = QRectF(QPoint(0, 0), scaled); 0166 destRect.moveCenter(boundingRect().center().toPoint()); 0167 break; 0168 } 0169 case TileVertically: { 0170 destRect = boundingRect().toRect(); 0171 destRect.setWidth(destRect.width() / (width() / (qreal)m_image.width())); 0172 break; 0173 } 0174 case TileHorizontally: { 0175 destRect = boundingRect().toRect(); 0176 destRect.setHeight(destRect.height() / (height() / (qreal)m_image.height())); 0177 break; 0178 } 0179 case Stretch: 0180 case Tile: 0181 case Pad: 0182 default: 0183 destRect = boundingRect().toRect(); 0184 } 0185 0186 if (destRect != sourceRect) { 0187 m_paintedRect = destRect.toRect(); 0188 Q_EMIT paintedHeightChanged(); 0189 Q_EMIT paintedWidthChanged(); 0190 } 0191 } 0192 0193 void QImageItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) 0194 { 0195 QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry); 0196 updatePaintedRect(); 0197 } 0198 0199 #include "moc_qimageitem.cpp"