1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QQUICKELLIPSESHAPE_P_P_H
#define QQUICKELLIPSESHAPE_P_P_H
#include "qquickellipseshape_p.h"
#include <QtQml/private/qqmlpropertyutils_p.h>
#include <QtQuickShapes/private/qquickshape_p_p.h>
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
QT_BEGIN_NAMESPACE
class Q_QUICKSHAPESDESIGNHELPERS_EXPORT QQuickEllipseShapePrivate : public QQuickShapePrivate
{
Q_DECLARE_PUBLIC(QQuickEllipseShape)
public:
QQuickEllipseShapePrivate();
~QQuickEllipseShapePrivate() override;
struct RoundedCorner
{
void update(qreal diff, QVector2D a, QVector2D b, QVector2D c, qreal alpha, qreal radius)
{
A = a;
B = b;
C = c;
this->alpha = alpha;
this->radius = radius;
this->diff = diff;
}
void reset()
{
A = QVector2D();
B = QVector2D();
C = QVector2D();
alpha = 0;
radius = 0;
diff = 0;
}
// A - a point, where the rounding corner is located
QVector2D A;
// B - tangent point of the rounded corner arc, which is located on the ellipse's arc
// for the rounded corner at the ellipse's center this is a point on the edge defined by the
// end angle
// for the rounded corner at the begin angle this is a point on the outer arc of the ellipse
QVector2D B;
// C - tangent point of the rounded corner arc, which is located on the ellipse's edge
// for the rounded corner at the ellipse's center this is a point on the edge defined by the
// begin angle
QVector2D C;
qreal alpha = 0; // angle between AB and AC
qreal radius = 0; // rounded corner radius
// not a rounded corner data, but a helper used to compare
// currently calculated radius to the previously calculated radius
qreal diff = 0;
};
enum class RoundedCornerIndex { Center, InnerEnd, OuterEnd, InnerBegin, OuterBegin };
// helper, to avoid typing static_cast<int>(RoundedCornerIndex) every time
class RoundedCornerArray
{
public:
RoundedCorner &operator[](RoundedCornerIndex index)
{
return array[static_cast<int>(index)];
}
void reset()
{
for (auto &rc : array)
rc.reset();
}
private:
RoundedCorner array[5];
} roundedCorners;
void addLine(QVector2D point);
void addArc(QVector2D point, QVector2D arcRadius, QQuickPathArc::ArcDirection dir,
bool largeArc = false);
qreal getBorderOffset() const;
// calculates rounded corner at the ellipse center
void roundCenter(QVector2D center, QVector2D ellipseRadius);
// runs loop where begin and end rounded corners are calculated
void roundBeginEnd(QVector2D center, QVector2D ellipseRadius);
// calculates rounded corners on the outer arc
bool roundOuter(QVector2D center, QVector2D ellipseRadius, qreal deg, qreal arcAngle1,
qreal arcAngle2, RoundedCornerIndex index);
// calculates rounded corners on the inner arc
bool roundInner(QVector2D center, QVector2D ellipseRadius, qreal deg, qreal arcAngle1,
qreal arcAngle2, RoundedCornerIndex index);
// starts path at the center rounded corner and draws center rounded corner
void drawCenterCorner();
// connects outer and inner arcs with line and draws end rounded corner
void drawInnerEndCorner();
// starts path at the begin rounded corner and draws begin rounded corner
void drawInnerBeginCorner();
// connects previous rounded corner (center or begin) with line and draws begin rounded corner
void drawOuterBeginCorner();
// draw outer arc path from begin rounded corner to the end rounded corner
void drawOuterArcRounded(QVector2D center, QVector2D ellipseRadius);
// draw inner arc path from end rounded corner to the begin rounded corner
void drawInnerArcRounded(QVector2D center, QVector2D ellipseRadius);
// draws outer arc when no rounded corners involved
void drawOuterArc(QVector2D center, QVector2D ellipseRadius);
// draws full inner arc (no rounded corners)
void drawFullInnerArc(QVector2D center, QVector2D ellipseRadius);
// draws an ellipse when inner radius is not zero
void drawWithInnerRadius(QVector2D center, QVector2D ellipseRadius);
// draws an ellipse when inner radius is greater than zero
void drawWithoutInnerRadius(QVector2D center, QVector2D ellipseRadius);
void updatePath();
QQuickShapePath *path = nullptr;
qreal startAngle = 0;
qreal sweepAngle = 360;
qreal innerArcRatio = 0;
qreal cornerRadius = 10;
QQuickEllipseShape::BorderMode borderMode = QQuickEllipseShape::BorderMode::Inside;
};
QT_END_NAMESPACE
#endif // QQUICKELLIPSE1SHAPE_P_P_H
|