Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qquickshapecurverenderer_p.h
Go to the documentation of this file.
1// Copyright (C) 2022 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
4#ifndef QQUICKSHAPECURVERENDERER_P_H
5#define QQUICKSHAPECURVERENDERER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of a number of Qt sources files. This header file may change from
13// version to version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtQuickShapes/private/qquickshapesglobal_p.h>
19#include <QtQuickShapes/private/qquickshape_p_p.h>
20#include <qsgnode.h>
21#include <qsggeometry.h>
22#include <qsgmaterial.h>
24#include <qsgtexture.h>
25#include <QtCore/qrunnable.h>
26
27#include <QtGui/private/qtriangulator_p.h>
28
30
32{
33public:
34 void moveTo(const QVector2D &to)
35 {
36 subPathToStart = true;
37 currentPoint = to;
38 }
39
40 void lineTo(const QVector2D &to)
41 {
42 addElement({}, to, true);
43 }
44
45 void quadTo(const QVector2D &control, const QVector2D &to)
46 {
47 addElement(control, to);
48 }
49
51
52 Qt::FillRule fillRule() const { return m_fillRule; }
53 void setFillRule(Qt::FillRule rule) { m_fillRule = rule; }
54
55 void reserve(qsizetype size) { m_elements.reserve(size); }
56 qsizetype elementCount() const { return m_elements.size(); }
57 bool isEmpty() const { return m_elements.size() == 0; }
59
63 QuadPath flattened() const;
64 QuadPath dashed(qreal lineWidth, const QList<qreal> &dashPattern, qreal dashOffset = 0) const;
65
66 class Element
67 {
68 public:
70 : m_isSubpathStart(false), m_isSubpathEnd(false), m_isLine(false)
71 {
72 }
73
74 bool isSubpathStart() const
75 {
76 return m_isSubpathStart;
77 }
78
79 bool isSubpathEnd() const
80 {
81 return m_isSubpathEnd;
82 }
83
84 bool isLine() const
85 {
86 return m_isLine;
87 }
88
89 bool isConvex() const
90 {
91 return m_curvatureFlags & Convex;
92 }
93
95 {
96 return sp;
97 }
98
100 {
101 return cp;
102 }
103
105 {
106 return ep;
107 }
108
110 {
111 return isLine() ? 0.5f * (sp + ep) : (0.25f * sp) + (0.5f * cp) + (0.25 * ep);
112 }
113
115
116 std::array<QVector2D, 3> ABC() const;
117
119
120 qsizetype childCount() const { return m_numChildren; }
121
123 {
124 Q_ASSERT(childNumber >= 0 && childNumber < childCount());
125 return -(m_firstChildIndex + 1 + childNumber);
126 }
127
128 QVector2D pointAtFraction(float t) const;
129
131 {
132 return isLine() ? (ep - sp) : ((1 - t) * 2 * (cp - sp)) + (t * 2 * (ep - cp));
133 }
134
136 {
137 const QVector2D tan = tangentAtFraction(t);
138 return QVector2D(-tan.y(), tan.x());
139 }
140
141 float extent() const;
142
144 {
145 if (isConvex)
146 m_curvatureFlags = Element::CurvatureFlags(m_curvatureFlags | Element::Convex);
147 else
148 m_curvatureFlags = Element::CurvatureFlags(m_curvatureFlags & ~Element::Convex);
149
150 }
151
152 private:
153 int intersectionsAtY(float y, float *fractions) const;
154
155 enum CurvatureFlags : quint8 {
156 CurvatureUndetermined = 0,
157 FillOnRight = 1,
158 Convex = 2
159 };
160
161 QVector2D sp;
162 QVector2D cp;
163 QVector2D ep;
164 int m_firstChildIndex = 0;
165 quint8 m_numChildren = 0;
166 CurvatureFlags m_curvatureFlags = CurvatureUndetermined;
167 quint8 m_isSubpathStart : 1;
168 quint8 m_isSubpathEnd : 1;
169 quint8 m_isLine : 1;
170 friend class QuadPath;
171 friend QDebug operator<<(QDebug, const QuadPath::Element &);
172 };
173
174 template<typename Func>
175 void iterateChildrenOf(Element &e, Func &&lambda)
176 {
177 const qsizetype lastChildIndex = e.m_firstChildIndex + e.childCount() - 1;
178 for (qsizetype i = e.m_firstChildIndex; i <= lastChildIndex; i++) {
179 Element &c = m_childElements[i];
180 if (c.childCount() > 0)
181 iterateChildrenOf(c, lambda);
182 else
183 lambda(c);
184 }
185 }
186
187 template<typename Func>
188 void iterateChildrenOf(const Element &e, Func &&lambda) const
189 {
190 const qsizetype lastChildIndex = e.m_firstChildIndex + e.childCount() - 1;
191 for (qsizetype i = e.m_firstChildIndex; i <= lastChildIndex; i++) {
192 const Element &c = m_childElements[i];
193 if (c.childCount() > 0)
194 iterateChildrenOf(c, lambda);
195 else
196 lambda(c);
197 }
198 }
199
200 template<typename Func>
201 void iterateElements(Func &&lambda)
202 {
203 for (auto &e : m_elements) {
204 if (e.childCount() > 0)
205 iterateChildrenOf(e, lambda);
206 else
207 lambda(e);
208 }
209 }
210
211 template<typename Func>
212 void iterateElements(Func &&lambda) const
213 {
214 for (auto &e : m_elements) {
215 if (e.childCount() > 0)
216 iterateChildrenOf(e, lambda);
217 else
218 lambda(e);
219 }
220 }
221
223 Element &elementAt(qsizetype i) { return i < 0 ? m_childElements[-(i + 1)] : m_elements[i]; }
225 {
226 return i < 0 ? m_childElements[-(i + 1)] : m_elements[i];
227 }
228
230 {
231 return elementAt(i).indexOfChild(childNumber);
232 }
233
234 void addCurvatureData();
235 bool contains(const QVector2D &v) const;
236
237private:
238 void addElement(const QVector2D &control, const QVector2D &to, bool isLine = false);
239 Element::CurvatureFlags coordinateOrderOfElement(const Element &element) const;
240 static bool isControlPointOnLeft(const Element &element);
241 static QVector2D closestPointOnLine(const QVector2D &start,
242 const QVector2D &end,
243 const QVector2D &p);
244 static bool isPointOnLeft(const QVector2D &p, const QVector2D &sp, const QVector2D &ep);
245 static bool isPointOnLine(const QVector2D &p, const QVector2D &sp, const QVector2D &ep);
246 static bool isPointNearLine(const QVector2D &p, const QVector2D &sp, const QVector2D &ep);
247
248 friend QDebug operator<<(QDebug, const QuadPath &);
249
250 bool subPathToStart = true;
251 Qt::FillRule m_fillRule = Qt::OddEvenFill;
252 QVector2D currentPoint;
253 QList<Element> m_elements;
254 QList<Element> m_childElements;
255};
256
259
261{
262public:
264 : m_rootNode(nullptr)
265 { }
266 ~QQuickShapeCurveRenderer() override;
267
268 void beginSync(int totalCount, bool *countChanged) override;
269 void setPath(int index, const QQuickPath *path) override;
270 void setStrokeColor(int index, const QColor &color) override;
271 void setStrokeWidth(int index, qreal w) override;
272 void setFillColor(int index, const QColor &color) override;
273 void setFillRule(int index, QQuickShapePath::FillRule fillRule) override;
274 void setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit) override;
275 void setCapStyle(int index, QQuickShapePath::CapStyle capStyle) override;
277 qreal dashOffset, const QVector<qreal> &dashPattern) override;
278 void setFillGradient(int index, QQuickShapeGradient *gradient) override;
279 void endSync(bool async) override;
280 void setAsyncCallback(void (*)(void *), void *) override;
281 Flags flags() const override { return Flags{}; }
282
283 void updateNode() override;
284
285 void setRootNode(QSGNode *node);
286
288
290 {
291 PathDirty = 0x01,
292 FillDirty = 0x02,
294 UniformsDirty = 0x08
295 };
296
300 DebugWireframe = 0x02
301 };
302
303 Q_QUICKSHAPES_PRIVATE_EXPORT static int debugVisualization();
304 Q_QUICKSHAPES_PRIVATE_EXPORT static void setDebugVisualization(int options);
305
306private:
307 struct PathData {
308
309 bool isFillVisible() const { return fillColor.alpha() > 0 || gradientType != NoGradient; }
310
311 bool isStrokeVisible() const
312 {
313 return validPenWidth && pen.color().alpha() > 0 && pen.style() != Qt::NoPen;
314 }
315
316 FillGradientType gradientType = NoGradient;
317 GradientDesc gradient;
318 QPainterPath originalPath;
320 QuadPath fillPath;
321 QuadPath strokePath;
322 QColor fillColor;
323 Qt::FillRule fillRule = Qt::OddEvenFill;
324 QPen pen;
325 int m_dirty = 0;
326 bool validPenWidth = true;
327 bool convexConcaveResolved = false;
328
329 NodeList fillNodes;
330 NodeList fillDebugNodes;
331 NodeList strokeNodes;
332 NodeList strokeDebugNodes;
333 };
334
335 void deleteAndClear(NodeList *nodeList);
336
337 QVector<QSGGeometryNode *> addFillNodes(const PathData &pathData, NodeList *debugNodes);
338 QVector<QSGGeometryNode *> addTriangulatingStrokerNodes(const PathData &pathData, NodeList *debugNodes);
339 QVector<QSGGeometryNode *> addCurveStrokeNodes(const PathData &pathData, NodeList *debugNodes);
340
341 void solveOverlaps(QuadPath &path);
342
343 QSGNode *m_rootNode;
344 QVector<PathData> m_paths;
345 static int debugVisualizationFlags;
346};
347
349
350#endif // QQUICKSHAPECURVERENDERER_P_H
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore
Definition qlist.h:74
\inmodule QtGui
\inmodule QtGui
Definition qpen.h:25
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
void beginSync(int totalCount, bool *countChanged) override
static Q_QUICKSHAPES_PRIVATE_EXPORT int debugVisualization()
static Q_QUICKSHAPES_PRIVATE_EXPORT void setDebugVisualization(int options)
void setFillGradient(int index, QQuickShapeGradient *gradient) override
QVector< QSGGeometryNode * > NodeList
void endSync(bool async) override
void setStrokeWidth(int index, qreal w) override
void setCapStyle(int index, QQuickShapePath::CapStyle capStyle) override
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 setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle, qreal dashOffset, const QVector< qreal > &dashPattern) override
void setPath(int index, const QQuickPath *path) override
void setAsyncCallback(void(*)(void *), void *) override
void setFillRule(int index, QQuickShapePath::FillRule fillRule) override
\inmodule QtCore\reentrant
Definition qrect.h:483
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
The QVector2D class represents a vector or vertex in 2D space.
Definition qvectornd.h:31
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
QVector2D pointAtFraction(float t) const
friend QDebug operator<<(QDebug, const QuadPath::Element &)
void setAsConvex(bool isConvex)
QVector3D HGForPoint(QVector2D p) const
std::array< QVector2D, 3 > ABC() const
qsizetype indexOfChild(qsizetype childNumber) const
QVector2D tangentAtFraction(float t) const
QVector3D uvForPoint(QVector2D p) const
QVector2D normalAtFraction(float t) const
qsizetype elementCount() const
static QuadPath fromPainterPath(const QPainterPath &path)
QuadPath flattened() const
void splitElementAt(qsizetype index)
void iterateChildrenOf(const Element &e, Func &&lambda) const
qsizetype elementCountRecursive() const
const Element & elementAt(qsizetype i) const
QPainterPath toPainterPath() const
qsizetype indexOfChildAt(qsizetype i, qsizetype childNumber) const
QuadPath subPathsClosed() const
void reserve(qsizetype size)
void lineTo(const QVector2D &to)
Qt::FillRule fillRule() const
void quadTo(const QVector2D &control, const QVector2D &to)
QuadPath dashed(qreal lineWidth, const QList< qreal > &dashPattern, qreal dashOffset=0) const
void iterateChildrenOf(Element &e, Func &&lambda)
friend QDebug operator<<(QDebug, const QuadPath &)
QRectF controlPointRect() const
void setFillRule(Qt::FillRule rule)
void iterateElements(Func &&lambda)
bool contains(const QVector2D &v) const
Element & elementAt(qsizetype i)
void moveTo(const QVector2D &to)
void iterateElements(Func &&lambda) const
double e
Combined button and popup list for selecting options.
@ NoPen
@ OddEvenFill
DBusConnection const char * rule
Flags
GLsizei const GLfloat * v
[13]
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLuint start
GLint y
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
GLsizei const GLchar *const * path
GLfloat GLfloat p
[1]
static bool isLine(const QBezier &bezier)
QDebug operator<<(QDebug, const QuadPath::Element &)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define sp
ptrdiff_t qsizetype
Definition qtypes.h:70
double qreal
Definition qtypes.h:92
unsigned char quint8
Definition qtypes.h:41
QObject::connect nullptr