Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickshapesoftwarerenderer.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
5#include <private/qquickpath_p_p.h>
6
8
9void QQuickShapeSoftwareRenderer::beginSync(int totalCount, bool *countChanged)
10{
11 if (m_sp.size() != totalCount) {
12 m_sp.resize(totalCount);
13 m_accDirty |= DirtyList;
14 *countChanged = true;
15 } else {
16 *countChanged = false;
17 }
18}
19
21{
22 ShapePathGuiData &d(m_sp[index]);
23 d.path = path ? path->path() : QPainterPath();
24 d.dirty |= DirtyPath;
25 m_accDirty |= DirtyPath;
26}
27
29{
30 ShapePathGuiData &d(m_sp[index]);
31 d.pen.setColor(color);
32 d.dirty |= DirtyPen;
33 m_accDirty |= DirtyPen;
34}
35
37{
38 ShapePathGuiData &d(m_sp[index]);
39 d.strokeWidth = w;
40 if (w >= 0.0f)
41 d.pen.setWidthF(w);
42 d.dirty |= DirtyPen;
43 m_accDirty |= DirtyPen;
44}
45
47{
48 ShapePathGuiData &d(m_sp[index]);
49 d.fillColor = color;
50 d.brush.setColor(color);
51 d.dirty |= DirtyBrush;
52 m_accDirty |= DirtyBrush;
53}
54
56{
57 ShapePathGuiData &d(m_sp[index]);
58 d.fillRule = Qt::FillRule(fillRule);
59 d.dirty |= DirtyFillRule;
60 m_accDirty |= DirtyFillRule;
61}
62
64{
65 ShapePathGuiData &d(m_sp[index]);
66 d.pen.setJoinStyle(Qt::PenJoinStyle(joinStyle));
67 d.pen.setMiterLimit(miterLimit);
68 d.dirty |= DirtyPen;
69 m_accDirty |= DirtyPen;
70}
71
73{
74 ShapePathGuiData &d(m_sp[index]);
75 d.pen.setCapStyle(Qt::PenCapStyle(capStyle));
76 d.dirty |= DirtyPen;
77 m_accDirty |= DirtyPen;
78}
79
81 qreal dashOffset, const QVector<qreal> &dashPattern)
82{
83 ShapePathGuiData &d(m_sp[index]);
84 switch (strokeStyle) {
86 d.pen.setStyle(Qt::SolidLine);
87 break;
89 d.pen.setStyle(Qt::CustomDashLine);
90 d.pen.setDashPattern(dashPattern);
91 d.pen.setDashOffset(dashOffset);
92 break;
93 default:
94 break;
95 }
96 d.dirty |= DirtyPen;
97 m_accDirty |= DirtyPen;
98}
99
100static inline void setupPainterGradient(QGradient *painterGradient, const QQuickShapeGradient &g)
101{
102 painterGradient->setStops(g.gradientStops()); // sorted
103 switch (g.spread()) {
105 painterGradient->setSpread(QGradient::PadSpread);
106 break;
108 painterGradient->setSpread(QGradient::RepeatSpread);
109 break;
111 painterGradient->setSpread(QGradient::ReflectSpread);
112 break;
113 default:
114 break;
115 }
116}
117
119{
120 ShapePathGuiData &d(m_sp[index]);
121 if (QQuickShapeLinearGradient *g = qobject_cast<QQuickShapeLinearGradient *>(gradient)) {
122 QLinearGradient painterGradient(g->x1(), g->y1(), g->x2(), g->y2());
123 setupPainterGradient(&painterGradient, *g);
124 d.brush = QBrush(painterGradient);
125 } else if (QQuickShapeRadialGradient *g = qobject_cast<QQuickShapeRadialGradient *>(gradient)) {
126 QRadialGradient painterGradient(g->centerX(), g->centerY(), g->centerRadius(),
127 g->focalX(), g->focalY(), g->focalRadius());
128 setupPainterGradient(&painterGradient, *g);
129 d.brush = QBrush(painterGradient);
130 } else if (QQuickShapeConicalGradient *g = qobject_cast<QQuickShapeConicalGradient *>(gradient)) {
131 QConicalGradient painterGradient(g->centerX(), g->centerY(), g->angle());
132 setupPainterGradient(&painterGradient, *g);
133 d.brush = QBrush(painterGradient);
134 } else {
135 d.brush = QBrush(d.fillColor);
136 }
137 d.dirty |= DirtyBrush;
138 m_accDirty |= DirtyBrush;
139}
140
142{
143 ShapePathGuiData &d(m_sp[index]);
144 if (!(transform.isIdentity() && d.brush.transform().isIdentity())) // No need to copy if both==I
145 d.brush.setTransform(transform.matrix().toTransform());
146 d.dirty |= DirtyBrush;
147 m_accDirty |= DirtyBrush;
148}
149
153
155{
156 m_node = node;
157 m_accDirty |= DirtyList;
158}
159
161{
162 if (!m_accDirty)
163 return;
164
165 const int count = m_sp.size();
166 const bool listChanged = m_accDirty & DirtyList;
167 if (listChanged)
168 m_node->m_sp.resize(count);
169
170 m_node->m_boundingRect = QRectF();
171
172 for (int i = 0; i < count; ++i) {
173 ShapePathGuiData &src(m_sp[i]);
174 QQuickShapeSoftwareRenderNode::ShapePathRenderData &dst(m_node->m_sp[i]);
175
176 if (listChanged || (src.dirty & DirtyPath)) {
177 dst.path = src.path;
178 dst.path.setFillRule(src.fillRule);
179 }
180
181 if (listChanged || (src.dirty & DirtyFillRule))
182 dst.path.setFillRule(src.fillRule);
183
184 if (listChanged || (src.dirty & DirtyPen)) {
185 dst.pen = src.pen;
186 dst.strokeWidth = src.strokeWidth;
187 }
188
189 if (listChanged || (src.dirty & DirtyBrush))
190 dst.brush = src.brush;
191
192 src.dirty = 0;
193
194 QRectF br = dst.path.boundingRect();
195 const float sw = qMax(1.0f, dst.strokeWidth);
196 br.adjust(-sw, -sw, sw, sw);
197 m_node->m_boundingRect |= br;
198 }
199
201 m_accDirty = 0;
202}
203
208
213
217
219{
220 if (m_sp.isEmpty())
221 return;
222
223 QSGRendererInterface *rif = m_item->window()->rendererInterface();
224 QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::PainterResource));
225 Q_ASSERT(p);
226
227 const QRegion *clipRegion = state->clipRegion();
228 if (clipRegion && !clipRegion->isEmpty())
229 p->setClipRegion(*clipRegion, Qt::ReplaceClip); // must be done before setTransform
230
231 p->setTransform(matrix()->toTransform());
232 p->setOpacity(inheritedOpacity());
233
234 for (const ShapePathRenderData &d : std::as_const(m_sp)) {
235 p->setPen(d.strokeWidth >= 0.0f && d.pen.color() != Qt::transparent ? d.pen : Qt::NoPen);
236 p->setBrush(d.brush.color() != Qt::transparent ? d.brush : Qt::NoBrush);
237 p->drawPath(d.path);
238 }
239}
240
241QSGRenderNode::StateFlags QQuickShapeSoftwareRenderNode::changedStates() const
242{
243 return {};
244}
245
246QSGRenderNode::RenderingFlags QQuickShapeSoftwareRenderNode::flags() const
247{
248 return BoundedRectRendering; // avoid fullscreen updates by saying we won't draw outside rect()
249}
250
252{
253 return m_boundingRect;
254}
255
\inmodule QtGui
Definition qbrush.h:30
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtGui
Definition qbrush.h:446
\inmodule QtGui
Definition qbrush.h:135
@ ReflectSpread
Definition qbrush.h:148
@ RepeatSpread
Definition qbrush.h:149
@ PadSpread
Definition qbrush.h:147
\inmodule QtGui
Definition qbrush.h:394
\inmodule QtGui
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
QQuickWindow * window() const
Returns the window in which this item is rendered.
RenderingFlags flags() const override
void releaseResources() override
This function is called when all custom graphics resources allocated by this node have to be freed im...
void render(const RenderState *state) override
This function is called by the renderer and should paint this node with directly invoking commands in...
StateFlags changedStates() const override
When the underlying rendering API is OpenGL, this function should return a mask where each bit repres...
void setStrokeColor(int index, const QColor &color) override
void setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit) override
void setFillColor(int index, const QColor &color) override
void setNode(QQuickShapeSoftwareRenderNode *node)
void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle, qreal dashOffset, const QVector< qreal > &dashPattern) override
void beginSync(int totalCount, bool *countChanged) override
void setCapStyle(int index, QQuickShapePath::CapStyle capStyle) override
void setPath(int index, const QQuickPath *path) override
void setFillGradient(int index, QQuickShapeGradient *gradient) override
void setFillRule(int index, QQuickShapePath::FillRule fillRule) override
void setStrokeWidth(int index, qreal w) override
void setFillTransform(int index, const QSGTransform &transform) override
\inmodule QtGui
Definition qbrush.h:412
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr void adjust(qreal x1, qreal y1, qreal x2, qreal y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition qrect.h:805
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
@ DirtyMaterial
Definition qsgnode.h:75
void markDirty(DirtyState bits)
Notifies all connected renderers that the node has dirty bits.
Definition qsgnode.cpp:624
qreal inheritedOpacity() const
const QMatrix4x4 * matrix() const
An interface providing access to some of the graphics API specific internals of the scenegraph.
else opt state
[0]
Combined button and popup list for selecting options.
@ ReplaceClip
@ transparent
Definition qnamespace.h:47
@ CustomDashLine
@ SolidLine
@ NoPen
PenJoinStyle
@ NoBrush
PenCapStyle
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLfloat GLfloat GLfloat w
[0]
GLuint index
[2]
GLenum GLenum GLsizei count
GLenum src
GLuint color
[2]
GLenum GLenum dst
GLboolean GLboolean g
GLuint GLenum GLenum transform
GLsizei const GLchar *const * path
GLfloat GLfloat p
[1]
static void setupPainterGradient(QGradient *painterGradient, const QQuickShapeGradient &g)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
double qreal
Definition qtypes.h:187
QGraphicsItem * item