1/*
2 SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org>
3 SPDX-FileCopyrightText: 2015 Luca Beltrame <lbeltrame@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "qimageitem.h"
9
10#include <QPainter>
11
12QImageItem::QImageItem(QQuickItem *parent)
13 : QQuickPaintedItem(parent)
14 , m_fillMode(QImageItem::Stretch)
15{
16 setFlag(flag: ItemHasContents, enabled: true);
17}
18
19QImageItem::~QImageItem()
20{
21}
22
23void QImageItem::setImage(const QImage &image)
24{
25 bool oldImageNull = m_image.isNull();
26 m_image = image;
27 updatePaintedRect();
28 update();
29 Q_EMIT nativeWidthChanged();
30 Q_EMIT nativeHeightChanged();
31 Q_EMIT imageChanged();
32 if (oldImageNull != m_image.isNull()) {
33 Q_EMIT nullChanged();
34 }
35}
36
37QImage QImageItem::image() const
38{
39 return m_image;
40}
41
42void QImageItem::resetImage()
43{
44 setImage(QImage());
45}
46
47int QImageItem::nativeWidth() const
48{
49 return m_image.size().width() / m_image.devicePixelRatio();
50}
51
52int QImageItem::nativeHeight() const
53{
54 return m_image.size().height() / m_image.devicePixelRatio();
55}
56
57QImageItem::FillMode QImageItem::fillMode() const
58{
59 return m_fillMode;
60}
61
62void QImageItem::setFillMode(QImageItem::FillMode mode)
63{
64 if (mode == m_fillMode) {
65 return;
66 }
67
68 m_fillMode = mode;
69 updatePaintedRect();
70 update();
71 Q_EMIT fillModeChanged();
72}
73
74void QImageItem::paint(QPainter *painter)
75{
76 if (m_image.isNull()) {
77 return;
78 }
79 painter->save();
80 painter->setRenderHint(hint: QPainter::Antialiasing, on: smooth());
81 painter->setRenderHint(hint: QPainter::SmoothPixmapTransform, on: smooth());
82
83 if (m_fillMode == TileVertically) {
84 painter->scale(sx: width() / (qreal)m_image.width(), sy: 1);
85 }
86
87 if (m_fillMode == TileHorizontally) {
88 painter->scale(sx: 1, sy: height() / (qreal)m_image.height());
89 }
90
91 if (m_fillMode == Pad) {
92 QRect centeredRect = m_paintedRect;
93 centeredRect.moveCenter(p: m_image.rect().center());
94 painter->drawImage(targetRect: m_paintedRect, image: m_image, sourceRect: centeredRect);
95 } else if (m_fillMode >= Tile) {
96 painter->drawTiledPixmap(rect: m_paintedRect, pm: QPixmap::fromImage(image: m_image));
97 } else {
98 painter->drawImage(targetRect: m_paintedRect, image: m_image, sourceRect: m_image.rect());
99 }
100
101 painter->restore();
102}
103
104bool QImageItem::isNull() const
105{
106 return m_image.isNull();
107}
108
109int QImageItem::paintedWidth() const
110{
111 if (m_image.isNull()) {
112 return 0;
113 }
114
115 return m_paintedRect.width();
116}
117
118int QImageItem::paintedHeight() const
119{
120 if (m_image.isNull()) {
121 return 0;
122 }
123
124 return m_paintedRect.height();
125}
126
127void QImageItem::updatePaintedRect()
128{
129 if (m_image.isNull()) {
130 return;
131 }
132
133 QRectF sourceRect = m_paintedRect;
134
135 QRectF destRect;
136
137 switch (m_fillMode) {
138 case PreserveAspectFit: {
139 QSizeF scaled = m_image.size();
140
141 scaled.scale(s: boundingRect().size(), mode: Qt::KeepAspectRatio);
142 destRect = QRectF(QPoint(0, 0), scaled);
143 destRect.moveCenter(p: boundingRect().center().toPoint());
144 break;
145 }
146 case PreserveAspectCrop: {
147 QSizeF scaled = m_image.size();
148
149 scaled.scale(s: boundingRect().size(), mode: Qt::KeepAspectRatioByExpanding);
150 destRect = QRectF(QPoint(0, 0), scaled);
151 destRect.moveCenter(p: boundingRect().center().toPoint());
152 break;
153 }
154 case TileVertically: {
155 destRect = boundingRect().toRect();
156 destRect.setWidth(destRect.width() / (width() / (qreal)m_image.width()));
157 break;
158 }
159 case TileHorizontally: {
160 destRect = boundingRect().toRect();
161 destRect.setHeight(destRect.height() / (height() / (qreal)m_image.height()));
162 break;
163 }
164 case Stretch:
165 case Tile:
166 case Pad:
167 default:
168 destRect = boundingRect().toRect();
169 }
170
171 if (destRect != sourceRect) {
172 m_paintedRect = destRect.toRect();
173 Q_EMIT paintedHeightChanged();
174 Q_EMIT paintedWidthChanged();
175 }
176}
177void QImageItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
178{
179 QQuickPaintedItem::geometryChange(newGeometry, oldGeometry);
180 updatePaintedRect();
181}
182
183#include "moc_qimageitem.cpp"
184

source code of kdeclarative/src/qmlcontrols/kquickcontrolsaddons/qimageitem.cpp