forked from flutter-team-archive/engine
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpath_component.h
More file actions
196 lines (139 loc) · 5.42 KB
/
Copy pathpath_component.h
File metadata and controls
196 lines (139 loc) · 5.42 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_IMPELLER_GEOMETRY_PATH_COMPONENT_H_
#define FLUTTER_IMPELLER_GEOMETRY_PATH_COMPONENT_H_
#include <functional>
#include <type_traits>
#include <variant>
#include <vector>
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/point.h"
#include "impeller/geometry/scalar.h"
namespace impeller {
/// @brief An interface for generating a multi contour polyline as a triangle
/// strip.
class VertexWriter {
public:
explicit VertexWriter(std::vector<Point>& points,
std::vector<uint16_t>& indices,
std::optional<Matrix> uv_transform);
~VertexWriter() = default;
void EndContour();
void Write(Point point);
private:
bool previous_contour_odd_points_ = false;
size_t contour_start_ = 0u;
std::vector<Point>& points_;
std::vector<uint16_t>& indices_;
std::optional<Matrix> uv_transform_;
};
struct LinearPathComponent {
Point p1;
Point p2;
LinearPathComponent() {}
LinearPathComponent(Point ap1, Point ap2) : p1(ap1), p2(ap2) {}
Point Solve(Scalar time) const;
void AppendPolylinePoints(std::vector<Point>& points) const;
std::vector<Point> Extrema() const;
bool operator==(const LinearPathComponent& other) const {
return p1 == other.p1 && p2 == other.p2;
}
std::optional<Vector2> GetStartDirection() const;
std::optional<Vector2> GetEndDirection() const;
};
// A component that represets a Quadratic Bézier curve.
struct QuadraticPathComponent {
// Start point.
Point p1;
// Control point.
Point cp;
// End point.
Point p2;
QuadraticPathComponent() {}
QuadraticPathComponent(Point ap1, Point acp, Point ap2)
: p1(ap1), cp(acp), p2(ap2) {}
Point Solve(Scalar time) const;
Point SolveDerivative(Scalar time) const;
void AppendPolylinePoints(Scalar scale_factor,
std::vector<Point>& points) const;
using PointProc = std::function<void(const Point& point)>;
void ToLinearPathComponents(Scalar scale_factor, const PointProc& proc) const;
void ToLinearPathComponents(Scalar scale, VertexWriter& writer) const;
std::vector<Point> Extrema() const;
bool operator==(const QuadraticPathComponent& other) const {
return p1 == other.p1 && cp == other.cp && p2 == other.p2;
}
std::optional<Vector2> GetStartDirection() const;
std::optional<Vector2> GetEndDirection() const;
};
// A component that represets a Cubic Bézier curve.
struct CubicPathComponent {
// Start point.
Point p1;
// The first control point.
Point cp1;
// The second control point.
Point cp2;
// End point.
Point p2;
CubicPathComponent() {}
explicit CubicPathComponent(const QuadraticPathComponent& q)
: p1(q.p1),
cp1(q.p1 + (q.cp - q.p1) * (2.0 / 3.0)),
cp2(q.p2 + (q.cp - q.p2) * (2.0 / 3.0)),
p2(q.p2) {}
CubicPathComponent(Point ap1, Point acp1, Point acp2, Point ap2)
: p1(ap1), cp1(acp1), cp2(acp2), p2(ap2) {}
Point Solve(Scalar time) const;
Point SolveDerivative(Scalar time) const;
void AppendPolylinePoints(Scalar scale, std::vector<Point>& points) const;
std::vector<Point> Extrema() const;
using PointProc = std::function<void(const Point& point)>;
void ToLinearPathComponents(Scalar scale, const PointProc& proc) const;
void ToLinearPathComponents(Scalar scale, VertexWriter& writer) const;
CubicPathComponent Subsegment(Scalar t0, Scalar t1) const;
bool operator==(const CubicPathComponent& other) const {
return p1 == other.p1 && cp1 == other.cp1 && cp2 == other.cp2 &&
p2 == other.p2;
}
std::optional<Vector2> GetStartDirection() const;
std::optional<Vector2> GetEndDirection() const;
private:
QuadraticPathComponent Lower() const;
};
struct ContourComponent {
Point destination;
bool is_closed = false;
ContourComponent() {}
explicit ContourComponent(Point p, bool is_closed = false)
: destination(p), is_closed(is_closed) {}
bool operator==(const ContourComponent& other) const {
return destination == other.destination && is_closed == other.is_closed;
}
};
using PathComponentVariant = std::variant<std::monostate,
const LinearPathComponent*,
const QuadraticPathComponent*,
const CubicPathComponent*>;
struct PathComponentStartDirectionVisitor {
std::optional<Vector2> operator()(const LinearPathComponent* component);
std::optional<Vector2> operator()(const QuadraticPathComponent* component);
std::optional<Vector2> operator()(const CubicPathComponent* component);
std::optional<Vector2> operator()(std::monostate monostate) {
return std::nullopt;
}
};
struct PathComponentEndDirectionVisitor {
std::optional<Vector2> operator()(const LinearPathComponent* component);
std::optional<Vector2> operator()(const QuadraticPathComponent* component);
std::optional<Vector2> operator()(const CubicPathComponent* component);
std::optional<Vector2> operator()(std::monostate monostate) {
return std::nullopt;
}
};
static_assert(!std::is_polymorphic<LinearPathComponent>::value);
static_assert(!std::is_polymorphic<QuadraticPathComponent>::value);
static_assert(!std::is_polymorphic<CubicPathComponent>::value);
} // namespace impeller
#endif // FLUTTER_IMPELLER_GEOMETRY_PATH_COMPONENT_H_