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
qquadpath_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 QQUADPATH_P_H
5#define QQUADPATH_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 <QtCore/qrect.h>
19#include <QtCore/qlist.h>
20#include <QtCore/qdebug.h>
21#include <QtGui/qvector2d.h>
22#include <QtGui/qpainterpath.h>
23#include <QtQuick/qtquickexports.h>
24
26
27class Q_QUICK_EXPORT QQuadPath
28{
29public:
30 // This is a copy of the flags in QQuickShapePath ### TODO: use a common definition
32 PathLinear = 0x1,
33 PathQuadratic = 0x2,
34 PathConvex = 0x4,
35 PathFillOnRight = 0x8,
36 PathSolid = 0x10,
37 PathNonIntersecting = 0x20,
38 PathNonOverlappingControlPointTriangles = 0x40
39 };
40 Q_DECLARE_FLAGS(PathHints, PathHint)
41
42 class Q_QUICK_EXPORT Element
43 {
44 public:
46 : m_isSubpathStart(false), m_isSubpathEnd(false), m_isLine(false)
47 {
48 }
49
51 : sp(s), cp(c), ep(e), m_isSubpathStart(false), m_isSubpathEnd(false), m_isLine(false)
52 {
53 }
54
55 bool isSubpathStart() const
56 {
57 return m_isSubpathStart;
58 }
59
60 bool isSubpathEnd() const
61 {
62 return m_isSubpathEnd;
63 }
64
65 bool isLine() const
66 {
67 return m_isLine;
68 }
69
70 bool isConvex() const
71 {
72 return m_curvatureFlags & Convex;
73 }
74
76 {
77 return sp;
78 }
79
81 {
82 return cp;
83 }
84
86 {
87 return ep;
88 }
89
91 {
92 return isLine() ? 0.5f * (sp + ep) : (0.25f * sp) + (0.5f * cp) + (0.25 * ep);
93 }
94
95 /* For a curve, returns the control point. For a line, returns an arbitrary point on the
96 * inside side of the line (assuming the curvature has been set for the path). The point
97 * doesn't need to actually be inside the shape: it just makes for easier calculations
98 * later when it is at the same side as the fill. */
100 {
101 if (isLine()) {
102 QVector2D normal(sp.y() - ep.y(), ep.x() - sp.x());
103 return m_curvatureFlags & Element::FillOnRight ? sp + normal : sp - normal;
104 } else {
105 return cp;
106 }
107 }
108
109 Element segmentFromTo(float t0, float t1) const;
110
111 Element reversed() const;
112
113 int childCount() const { return m_numChildren; }
114
115 int indexOfChild(int childNumber) const
116 {
117 Q_ASSERT(childNumber >= 0 && childNumber < childCount());
118 return -(m_firstChildIndex + 1 + childNumber);
119 }
120
121 QVector2D pointAtFraction(float t) const;
122
124 {
125 return isLine() ? (ep - sp) : ((1 - t) * 2 * (cp - sp)) + (t * 2 * (ep - cp));
126 }
127
129 {
130 const QVector2D tan = tangentAtFraction(t);
131 return QVector2D(-tan.y(), tan.x());
132 }
133
134 float extent() const;
135
136 void setAsConvex(bool isConvex)
137 {
138 if (isConvex)
139 m_curvatureFlags = Element::CurvatureFlags(m_curvatureFlags | Element::Convex);
140 else
141 m_curvatureFlags = Element::CurvatureFlags(m_curvatureFlags & ~Element::Convex);
142 }
143
144 void setFillOnRight(bool isFillOnRight)
145 {
146 if (isFillOnRight)
147 m_curvatureFlags = Element::CurvatureFlags(m_curvatureFlags | Element::FillOnRight);
148 else
149 m_curvatureFlags = Element::CurvatureFlags(m_curvatureFlags & ~Element::FillOnRight);
150 }
151
152 bool isFillOnRight() const { return m_curvatureFlags & FillOnRight; }
153
155 {
156 return isPointOnLeft(cp, sp, ep);
157 }
158
160 CurvatureUndetermined = 0,
161 FillOnRight = 1,
162 Convex = 2
163 };
164
166 FillSideUndetermined = 0,
167 FillSideRight = 1,
168 FillSideLeft = 2,
169 FillSideBoth = 3
170 };
171
172 private:
173 int intersectionsAtY(float y, float *fractions, bool swapXY = false) const;
174
176 QVector2D cp;
177 QVector2D ep;
178 int m_firstChildIndex = 0;
179 quint8 m_numChildren = 0;
180 CurvatureFlags m_curvatureFlags = CurvatureUndetermined;
181 quint8 m_isSubpathStart : 1;
182 quint8 m_isSubpathEnd : 1;
183 quint8 m_isLine : 1;
184 friend class QQuadPath;
185 friend Q_QUICK_EXPORT QDebug operator<<(QDebug, const QQuadPath::Element &);
186 };
187
188 void moveTo(const QVector2D &to)
189 {
190 m_subPathToStart = true;
191 m_currentPoint = to;
192 }
193
194 void lineTo(const QVector2D &to)
195 {
196 addElement({}, to, true);
197 }
198
199 void quadTo(const QVector2D &control, const QVector2D &to)
200 {
201 addElement(control, to);
202 }
203
205 {
206 return i < 0 ? m_childElements[-(i + 1)] : m_elements[i];
207 }
208
209 const Element &elementAt(int i) const
210 {
211 return i < 0 ? m_childElements[-(i + 1)] : m_elements[i];
212 }
213
214 int indexOfChildAt(int i, int childNumber) const
215 {
216 return elementAt(i).indexOfChild(childNumber);
217 }
218
219 QRectF controlPointRect() const;
220
221 Qt::FillRule fillRule() const { return m_windingFill ? Qt::WindingFill : Qt::OddEvenFill; }
222 void setFillRule(Qt::FillRule rule) { m_windingFill = (rule == Qt::WindingFill); }
223
224 void reserve(int size) { m_elements.reserve(size); }
225 int elementCount() const { return m_elements.size(); }
226 bool isEmpty() const { return m_elements.size() == 0; }
227 int elementCountRecursive() const;
228
229 static QQuadPath fromPainterPath(const QPainterPath &path, PathHints hints = {});
230 QPainterPath toPainterPath() const;
231 QString asSvgString() const;
232
233 QQuadPath subPathsClosed(bool *didClose = nullptr) const;
234 void addCurvatureData();
235 QQuadPath flattened() const;
236 QQuadPath dashed(qreal lineWidth, const QList<qreal> &dashPattern, qreal dashOffset = 0) const;
237 void splitElementAt(int index);
238 bool contains(const QVector2D &point) const;
239 bool contains(const QVector2D &point, int fromIndex, int toIndex) const;
240 Element::FillSide fillSideOf(int elementIdx, float elementT) const;
241
242 template<typename Func>
243 void iterateChildrenOf(Element &e, Func &&lambda)
244 {
245 const int lastChildIndex = e.m_firstChildIndex + e.childCount() - 1;
246 for (int i = e.m_firstChildIndex; i <= lastChildIndex; i++) {
247 Element &c = m_childElements[i];
248 if (c.childCount() > 0)
249 iterateChildrenOf(c, lambda);
250 else
251 lambda(c, -(i + 1));
252 }
253 }
254
255 template<typename Func>
256 void iterateChildrenOf(const Element &e, Func &&lambda) const
257 {
258 const int lastChildIndex = e.m_firstChildIndex + e.childCount() - 1;
259 for (int i = e.m_firstChildIndex; i <= lastChildIndex; i++) {
260 const Element &c = m_childElements[i];
261 if (c.childCount() > 0)
262 iterateChildrenOf(c, lambda);
263 else
264 lambda(c, -(i + 1));
265 }
266 }
267
268 template<typename Func>
269 void iterateElements(Func &&lambda)
270 {
271 for (int i = 0; i < m_elements.size(); i++) {
272 Element &e = m_elements[i];
273 if (e.childCount() > 0)
274 iterateChildrenOf(e, lambda);
275 else
276 lambda(e, i);
277 }
278 }
279
280 template<typename Func>
281 void iterateElements(Func &&lambda) const
282 {
283 for (int i = 0; i < m_elements.size(); i++) {
284 const Element &e = m_elements[i];
285 if (e.childCount() > 0)
286 iterateChildrenOf(e, lambda);
287 else
288 lambda(e, i);
289 }
290 }
291
292 static QVector2D closestPointOnLine(const QVector2D &p, const QVector2D &sp, const QVector2D &ep);
293 static bool isPointOnLeft(const QVector2D &p, const QVector2D &sp, const QVector2D &ep);
294 static bool isPointOnLine(const QVector2D &p, const QVector2D &sp, const QVector2D &ep);
295 static bool isPointNearLine(const QVector2D &p, const QVector2D &sp, const QVector2D &ep);
296
298 {
299 return m_hints.testFlag(hint);
300 }
301
302 void setHint(PathHint hint, bool on = true)
303 {
304 m_hints.setFlag(hint, on);
305 }
306
307 PathHints pathHints() const
308 {
309 return m_hints;
310 }
311
312 void setPathHints(PathHints newHints)
313 {
314 m_hints = newHints;
315 }
316
317private:
318 void addElement(const QVector2D &control, const QVector2D &to, bool isLine = false);
319 void addElement(const Element &e);
320 Element::CurvatureFlags coordinateOrderOfElement(const Element &element) const;
321
322 friend Q_QUICK_EXPORT QDebug operator<<(QDebug, const QQuadPath &);
323
324 QList<Element> m_elements;
325 QList<Element> m_childElements;
326 QVector2D m_currentPoint;
327 bool m_subPathToStart = true;
328 bool m_windingFill = false;
329 PathHints m_hints;
330
331 friend class QSGCurveProcessor;
332};
333
334Q_DECLARE_OPERATORS_FOR_FLAGS(QQuadPath::PathHints);
335
336Q_QUICK_EXPORT QDebug operator<<(QDebug, const QQuadPath::Element &);
337Q_QUICK_EXPORT QDebug operator<<(QDebug, const QQuadPath &);
338
340
341#endif
\inmodule QtCore
\inmodule QtGui
bool isSubpathStart() const
Definition qquadpath_p.h:55
bool isControlPointOnLeft() const
bool isFillOnRight() const
QVector2D normalAtFraction(float t) const
void setFillOnRight(bool isFillOnRight)
int indexOfChild(int childNumber) const
bool isLine() const
Definition qquadpath_p.h:65
int childCount() const
QVector2D tangentAtFraction(float t) const
bool isSubpathEnd() const
Definition qquadpath_p.h:60
QVector2D startPoint() const
Definition qquadpath_p.h:75
void setAsConvex(bool isConvex)
QVector2D midPoint() const
Definition qquadpath_p.h:90
bool isConvex() const
Definition qquadpath_p.h:70
QVector2D endPoint() const
Definition qquadpath_p.h:85
Element(QVector2D s, QVector2D c, QVector2D e)
Definition qquadpath_p.h:50
QVector2D referencePoint() const
Definition qquadpath_p.h:99
QVector2D controlPoint() const
Definition qquadpath_p.h:80
void lineTo(const QVector2D &to)
void setHint(PathHint hint, bool on=true)
Element & elementAt(int i)
void quadTo(const QVector2D &control, const QVector2D &to)
void iterateElements(Func &&lambda)
void iterateElements(Func &&lambda) const
void iterateChildrenOf(const Element &e, Func &&lambda) const
void reserve(int size)
bool isEmpty() const
void iterateChildrenOf(Element &e, Func &&lambda)
PathHints pathHints() const
int indexOfChildAt(int i, int childNumber) const
const Element & elementAt(int i) const
void setPathHints(PathHints newHints)
Qt::FillRule fillRule() const
void moveTo(const QVector2D &to)
bool testHint(PathHint hint) const
void setFillRule(Qt::FillRule rule)
int elementCount() const
\inmodule QtCore\reentrant
Definition qrect.h:484
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
The QVector2D class represents a vector or vertex in 2D space.
Definition qvectornd.h:31
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
Combined button and popup list for selecting options.
@ WindingFill
@ OddEvenFill
DBusConnection const char * rule
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition qflags.h:174
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition qflags.h:194
static bool contains(const QJsonArray &haystack, unsigned needle)
Definition qopengl.cpp:116
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
[4]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
GLint y
GLdouble s
[6]
Definition qopenglext.h:235
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)
Q_QUICK_EXPORT QDebug operator<<(QDebug, const QQuadPath::Element &)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define sp
double qreal
Definition qtypes.h:187
unsigned char quint8
Definition qtypes.h:46
static uint toIndex(ExecutionEngine *e, const Value &v)
QDataStream & operator<<(QDataStream &out, const MyClass &myObj)
[4]