Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsgsoftwarepainternode.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
7#include <qmath.h>
8
10
11QSGSoftwarePainterNode::QSGSoftwarePainterNode(QQuickPaintedItem *item)
12 : QSGPainterNode()
13 , m_preferredRenderTarget(QQuickPaintedItem::Image)
14 , m_item(item)
15 , m_texture(nullptr)
16 , m_dirtyContents(false)
17 , m_opaquePainting(false)
18 , m_linear_filtering(false)
19 , m_mipmapping(false)
20 , m_smoothPainting(false)
21 , m_fastFBOResizing(false)
22 , m_fillColor(Qt::transparent)
23 , m_contentsScale(1.0)
24 , m_dirtyGeometry(false)
25{
26 setMaterial((QSGMaterial*)1);
27 setGeometry((QSGGeometry*)1);
28}
29
30QSGSoftwarePainterNode::~QSGSoftwarePainterNode()
31{
32 delete m_texture;
33}
34
35void QSGSoftwarePainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target)
36{
37 if (m_preferredRenderTarget == target)
38 return;
39
40 m_preferredRenderTarget = target;
41}
42
43void QSGSoftwarePainterNode::setSize(const QSize &size)
44{
45 if (size == m_size)
46 return;
47
48 m_size = size;
49
50 m_dirtyGeometry = true;
51}
52
53void QSGSoftwarePainterNode::setDirty(const QRect &dirtyRect)
54{
55 m_dirtyContents = true;
56 m_dirtyRect = dirtyRect;
57 markDirty(DirtyMaterial);
58}
59
60void QSGSoftwarePainterNode::setOpaquePainting(bool opaque)
61{
62 if (opaque == m_opaquePainting)
63 return;
64
65 m_opaquePainting = opaque;
66}
67
68void QSGSoftwarePainterNode::setLinearFiltering(bool linearFiltering)
69{
70 if (linearFiltering == m_linear_filtering)
71 return;
72
73 m_linear_filtering = linearFiltering;
74}
75
76void QSGSoftwarePainterNode::setMipmapping(bool mipmapping)
77{
78 if (mipmapping == m_mipmapping)
79 return;
80
81 m_mipmapping = mipmapping;
82}
83
84void QSGSoftwarePainterNode::setSmoothPainting(bool s)
85{
86 if (s == m_smoothPainting)
87 return;
88
89 m_smoothPainting = s;
90}
91
92void QSGSoftwarePainterNode::setFillColor(const QColor &c)
93{
94 if (c == m_fillColor)
95 return;
96
97 m_fillColor = c;
98 markDirty(DirtyMaterial);
99}
100
101void QSGSoftwarePainterNode::setContentsScale(qreal s)
102{
103 if (s == m_contentsScale)
104 return;
105
106 m_contentsScale = s;
107 markDirty(DirtyMaterial);
108}
109
110void QSGSoftwarePainterNode::setFastFBOResizing(bool dynamic)
111{
112 m_fastFBOResizing = dynamic;
113}
114
115QImage QSGSoftwarePainterNode::toImage() const
116{
117 return m_pixmap.toImage();
118}
119
120void QSGSoftwarePainterNode::update()
121{
122 if (m_dirtyGeometry) {
123 m_pixmap = QPixmap(m_textureSize);
124 if (!m_opaquePainting)
125 m_pixmap.fill(Qt::transparent);
126
127 if (m_texture)
128 delete m_texture;
129 m_texture = new QSGSoftwarePixmapTexture(m_pixmap);
130 }
131
132 if (m_dirtyContents)
133 paint();
134
135 m_dirtyGeometry = false;
136 m_dirtyContents = false;
137}
138
139void QSGSoftwarePainterNode::paint(QPainter *painter)
140{
141 bool before = painter->testRenderHint(QPainter::SmoothPixmapTransform);
142 painter->setRenderHint(QPainter::SmoothPixmapTransform, m_linear_filtering);
143 painter->drawPixmap(0, 0, m_size.width(), m_size.height(), m_pixmap);
144 painter->setRenderHint(QPainter::SmoothPixmapTransform, before);
145}
146
147void QSGSoftwarePainterNode::paint()
148{
149 QRect dirtyRect = m_dirtyRect.isNull() ? QRect(0, 0, m_size.width(), m_size.height()) : m_dirtyRect;
150
151 QPainter painter;
152
153 painter.begin(&m_pixmap);
154 if (m_smoothPainting) {
155 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
156 }
157
158 QRect clipRect;
159
160 if (m_contentsScale == 1) {
161 qreal scaleX = m_textureSize.width() / (qreal) m_size.width();
162 qreal scaleY = m_textureSize.height() / (qreal) m_size.height();
163 painter.scale(scaleX, scaleY);
164 clipRect = dirtyRect;
165 } else {
166 painter.scale(m_contentsScale, m_contentsScale);
167
168 QRect sclip(qFloor(dirtyRect.x()/m_contentsScale),
169 qFloor(dirtyRect.y()/m_contentsScale),
170 qCeil(dirtyRect.width()/m_contentsScale+dirtyRect.x()/m_contentsScale-qFloor(dirtyRect.x()/m_contentsScale)),
171 qCeil(dirtyRect.height()/m_contentsScale+dirtyRect.y()/m_contentsScale-qFloor(dirtyRect.y()/m_contentsScale)));
172
173 clipRect = sclip;
174 }
175
176 if (!m_dirtyRect.isNull())
177 painter.setClipRect(clipRect);
178
179 painter.setCompositionMode(QPainter::CompositionMode_Source);
180 painter.fillRect(clipRect, m_fillColor);
181 painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
182
183 m_item->paint(&painter);
184 painter.end();
185
186 m_dirtyRect = QRect();
187}
188
189
190void QSGSoftwarePainterNode::setTextureSize(const QSize &size)
191{
192 if (size == m_textureSize)
193 return;
194
195 m_textureSize = size;
196 m_dirtyGeometry = true;
197}
198
199QT_END_NAMESPACE
The QQuickPaintedItem class provides a way to use the QPainter API in the QML Scene Graph.
Combined button and popup list for selecting options.