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