KDeclarative

qpixmapitem.cpp
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 "qpixmapitem.h"
9
10#include <QPainter>
11#include <QQuickWindow>
12
13QPixmapItem::QPixmapItem(QQuickItem *parent)
14 : QQuickPaintedItem(parent)
15 , m_fillMode(QPixmapItem::Stretch)
16{
17 setFlag(ItemHasContents, true);
18}
19
20QPixmapItem::~QPixmapItem()
21{
22}
23
24void QPixmapItem::setPixmap(const QPixmap &pixmap)
25{
26 bool oldPixmapNull = m_pixmap.isNull();
27 m_pixmap = pixmap;
28 updatePaintedRect();
29 update();
30 Q_EMIT nativeWidthChanged();
31 Q_EMIT nativeHeightChanged();
32 Q_EMIT pixmapChanged();
33 if (oldPixmapNull != m_pixmap.isNull()) {
34 Q_EMIT nullChanged();
35 }
36}
37
38QPixmap QPixmapItem::pixmap() const
39{
40 return m_pixmap;
41}
42
43void QPixmapItem::resetPixmap()
44{
45 setPixmap(QPixmap());
46}
47
48int QPixmapItem::nativeWidth() const
49{
50 return m_pixmap.size().width() / m_pixmap.devicePixelRatio();
51}
52
53int QPixmapItem::nativeHeight() const
54{
55 return m_pixmap.size().height() / m_pixmap.devicePixelRatio();
56}
57
58QPixmapItem::FillMode QPixmapItem::fillMode() const
59{
60 return m_fillMode;
61}
62
63void QPixmapItem::setFillMode(QPixmapItem::FillMode mode)
64{
65 if (mode == m_fillMode) {
66 return;
67 }
68
69 m_fillMode = mode;
70 updatePaintedRect();
71 update();
72 Q_EMIT fillModeChanged();
73}
74
75void QPixmapItem::paint(QPainter *painter)
76{
77 if (m_pixmap.isNull()) {
78 return;
79 }
80 painter->save();
83
84 if (m_fillMode == TileVertically) {
85 painter->scale(width() / (qreal)m_pixmap.width(), 1);
86 }
87
88 if (m_fillMode == TileHorizontally) {
89 painter->scale(1, height() / (qreal)m_pixmap.height());
90 }
91
92 if (m_fillMode >= Tile) {
93 painter->drawTiledPixmap(m_paintedRect, m_pixmap);
94 } else {
95 painter->drawPixmap(m_paintedRect, m_pixmap, m_pixmap.rect());
96 }
97
98 painter->restore();
99}
100
101bool QPixmapItem::isNull() const
102{
103 return m_pixmap.isNull();
104}
105
106int QPixmapItem::paintedWidth() const
107{
108 if (m_pixmap.isNull()) {
109 return 0;
110 }
111
112 return m_paintedRect.width();
113}
114
115int QPixmapItem::paintedHeight() const
116{
117 if (m_pixmap.isNull()) {
118 return 0;
119 }
120
121 return m_paintedRect.height();
122}
123
124void QPixmapItem::updatePaintedRect()
125{
126 if (m_pixmap.isNull()) {
127 return;
128 }
129
130 QRectF sourceRect = m_paintedRect;
131
132 QRectF destRect;
133 QRectF bounds = boundingRect();
134
135 auto posAdjusted = [this](const QPointF point) {
136 auto w = window();
137 if (!w) {
138 return point;
139 }
140 const auto effectiveDpr = w->effectiveDevicePixelRatio();
141 QPointF globalPixelPos = mapToScene(point) * effectiveDpr;
142 QPointF posAdjust = QPointF(globalPixelPos.x() - std::round(globalPixelPos.x()), globalPixelPos.y() - std::round(globalPixelPos.y())) / effectiveDpr;
143 return (point - posAdjust);
144 };
145
146 switch (m_fillMode) {
147 case PreserveAspectFit: {
148 QSizeF scaled = m_pixmap.size();
150 destRect = QRectF(QPoint(0, 0), scaled);
151 destRect.moveCenter(posAdjusted(bounds.center()));
152 break;
153 }
154 case PreserveAspectCrop: {
155 QSizeF scaled = m_pixmap.size();
157 destRect = QRectF(QPoint(0, 0), scaled);
158 destRect.moveCenter(posAdjusted(bounds.center()));
159 break;
160 }
161 case TileVertically: {
162 destRect = bounds.toRect();
163 destRect.setWidth(destRect.width() / (width() / (qreal)m_pixmap.width()));
164 break;
165 }
166 case TileHorizontally: {
167 destRect = bounds.toRect();
168 destRect.setHeight(destRect.height() / (height() / (qreal)m_pixmap.height()));
169 break;
170 }
171 case Stretch:
172 case Tile:
173 default:
174 destRect = bounds.toRect();
175 }
176
177 if (destRect != sourceRect) {
178 m_paintedRect = destRect.toRect();
179 Q_EMIT paintedHeightChanged();
180 Q_EMIT paintedWidthChanged();
181 }
182}
183
184void QPixmapItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
185{
186 QQuickPaintedItem::geometryChange(newGeometry, oldGeometry);
187 updatePaintedRect();
188}
189
190#include "moc_qpixmapitem.cpp"
Q_EMITQ_EMIT
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
void drawTiledPixmap(const QRect &rectangle, const QPixmap &pixmap, const QPoint &position)
void restore()
void save()
void scale(qreal sx, qreal sy)
void setRenderHint(RenderHint hint, bool on)
qreal devicePixelRatio() const const
int height() const const
bool isNull() const const
QRect rect() const const
QSize size() const const
int width() const const
qreal x() const const
qreal y() const const
virtual QRectF boundingRect() const const
virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
QPointF mapToScene(const QPointF &point) const const
QSizeF size() const const
void update()
QQuickWindow * window() const const
int height() const const
int width() const const
QPointF center() const const
qreal height() const const
void moveCenter(const QPointF &position)
void setHeight(qreal height)
void setWidth(qreal width)
QRect toRect() const const
qreal width() const const
int height() const const
int width() const const
void scale(const QSizeF &size, Qt::AspectRatioMode mode)
KeepAspectRatio
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:05:54 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.