| Flutter Impeller |

path.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_IMPELLER_GEOMETRY_PATH_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_PATH_H_
7
8 #include <functional>
9 #include <optional>
10 #include <set>
11 #include <tuple>
12 #include <vector>
13
14 #include "impeller/geometry/path_component.h"
15
16 namespace impeller {
17
18 enum class Cap {
19 kButt,
20 kRound,
21 kSquare,
22 };
23
24 enum class Join {
25 kMiter,
26 kRound,
27 kBevel,
28 };
29
30 enum class FillType {
31 kNonZero, // The default winding order.
32 kOdd,
33 kPositive,
34 kNegative,
35 kAbsGeqTwo,
36 };
37
38 enum class Convexity {
39 kUnknown,
40 kConvex,
41 };
42
43 //------------------------------------------------------------------------------
44 /// @brief Paths are lightweight objects that describe a collection of
45 /// linear, quadratic, or cubic segments. These segments may be
46 /// broken up by move commands, which are effectively linear
47 /// commands that pick up the pen rather than continuing to draw.
48 ///
49 /// All shapes supported by Impeller are paths either directly or
50 /// via approximation (in the case of circles).
51 ///
52 /// Paths are externally immutable once created, Creating paths must
53 /// be done using a path builder.
54 ///
55 class Path {
56 public:
57 enum class ComponentType {
58 kLinear,
59 kQuadratic,
60 kCubic,
61 kContour,
62 };
63
64 struct PolylineContour {
65 struct Component {
66 size_t component_start_index;
67 /// Denotes whether this component is a curve.
68 ///
69 /// This is set to true when this component is generated from
70 /// QuadraticComponent or CubicPathComponent.
71 bool is_curve;
72 };
73 /// Index that denotes the first point of this contour.
74 size_t start_index;
75
76 /// Denotes whether the last point of this contour is connected to the first
77 /// point of this contour or not.
78 bool is_closed;
79
80 /// The direction of the contour's start cap.
81 Vector2 start_direction;
82 /// The direction of the contour's end cap.
83 Vector2 end_direction;
84
85 /// Distinct components in this contour.
86 ///
87 /// If this contour is generated from multiple path components, each
88 /// path component forms a component in this vector.
89 std::vector<Component> components;
90 };
91
92 /// One or more contours represented as a series of points and indices in
93 /// the point vector representing the start of a new contour.
94 ///
95 /// Polylines are ephemeral and meant to be used by the tessellator. They do
96 /// not allocate their own point vectors to allow for optimizations around
97 /// allocation and reuse of arenas.
98 struct Polyline {
99 /// The signature of a method called when it is safe to reclaim the point
100 /// buffer provided to the constructor of this object.
101 using PointBufferPtr = std::unique_ptr<std::vector<Point>>;
102 using ReclaimPointBufferCallback = std::function<void(PointBufferPtr)>;
103
104 /// The buffer will be cleared and returned at the destruction of this
105 /// polyline.
106 Polyline(PointBufferPtr point_buffer, ReclaimPointBufferCallback reclaim);
107
108 Polyline(Polyline&& other);
109 ~Polyline();
110
111 /// Points in the polyline, which may represent multiple contours specified
112 /// by indices in |contours|.
113 PointBufferPtr points;
114
115 Point& GetPoint(size_t index) const { return (*points)[index]; }
116
117 /// Contours are disconnected pieces of a polyline, such as when a MoveTo
118 /// was issued on a PathBuilder.
119 std::vector<PolylineContour> contours;
120
121 /// Convenience method to compute the start (inclusive) and end (exclusive)
122 /// point of the given contour index.
123 ///
124 /// The contour_index parameter is clamped to contours.size().
125 std::tuple<size_t, size_t> GetContourPointBounds(
126 size_t contour_index) const;
127
128 private:
129 ReclaimPointBufferCallback reclaim_points_;
130 };
131
132 Path();
133
134 ~Path();
135
136 Path(Path&& other) = default;
137
138 /// @brief Deeply clone this path and all data associated with it.
139 Path Clone() const;
140
141 size_t GetComponentCount(std::optional<ComponentType> type = {}) const;
142
143 FillType GetFillType() const;
144
145 bool IsConvex() const;
146
147 template <class T>
148 using Applier = std::function<void(size_t index, const T& component)>;
149 void EnumerateComponents(
150 const Applier<LinearPathComponent>& linear_applier,
151 const Applier<QuadraticPathComponent>& quad_applier,
152 const Applier<CubicPathComponent>& cubic_applier,
153 const Applier<ContourComponent>& contour_applier) const;
154
155 bool GetLinearComponentAtIndex(size_t index,
156 LinearPathComponent& linear) const;
157
158 bool GetQuadraticComponentAtIndex(size_t index,
159 QuadraticPathComponent& quadratic) const;
160
161 bool GetCubicComponentAtIndex(size_t index, CubicPathComponent& cubic) const;
162
163 bool GetContourComponentAtIndex(size_t index,
164 ContourComponent& contour) const;
165
166 /// Callers must provide the scale factor for how this path will be
167 /// transformed.
168 ///
169 /// It is suitable to use the max basis length of the matrix used to transform
170 /// the path. If the provided scale is 0, curves will revert to straight
171 /// lines.
172 Polyline CreatePolyline(
173 Scalar scale,
174 Polyline::PointBufferPtr point_buffer =
175 std::make_unique<std::vector<Point>>(),
176 Polyline::ReclaimPointBufferCallback reclaim = nullptr) const;
177
178 std::optional<Rect> GetBoundingBox() const;
179
180 std::optional<Rect> GetTransformedBoundingBox(const Matrix& transform) const;
181
182 std::optional<std::pair<Point, Point>> GetMinMaxCoveragePoints() const;
183
184 private:
185 friend class PathBuilder;
186
187 Path(const Path& other) = default;
188
189 void SetConvexity(Convexity value);
190
191 void SetFillType(FillType fill);
192
193 void SetBounds(Rect rect);
194
195 Path& AddLinearComponent(const Point& p1, const Point& p2);
196
197 Path& AddQuadraticComponent(const Point& p1,
198 const Point& cp,
199 const Point& p2);
200
201 Path& AddCubicComponent(const Point& p1,
202 const Point& cp1,
203 const Point& cp2,
204 const Point& p2);
205
206 Path& AddContourComponent(const Point& destination, bool is_closed = false);
207
208 /// @brief Called by `PathBuilder` to compute the bounds for certain paths.
209 ///
210 /// `PathBuilder` may set the bounds directly, in case they come from a source
211 /// with already computed bounds, such as an SkPath.
212 void ComputeBounds();
213
214 void SetContourClosed(bool is_closed);
215
216 void Shift(Point shift);
217
218 struct ComponentIndexPair {
219 ComponentType type = ComponentType::kLinear;
220 size_t index = 0;
221
222 ComponentIndexPair() {}
223
224 ComponentIndexPair(ComponentType a_type, size_t a_index)
225 : type(a_type), index(a_index) {}
226 };
227
228 FillType fill_ = FillType::kNonZero;
229 Convexity convexity_ = Convexity::kUnknown;
230 std::vector<ComponentIndexPair> components_;
231 std::vector<Point> points_;
232 std::vector<ContourComponent> contours_;
233
234 std::optional<Rect> computed_bounds_;
235 };
236
237 } // namespace impeller
238
239 #endif // FLUTTER_IMPELLER_GEOMETRY_PATH_H_
impeller::Cap::kRound
@ kRound
impeller::Cap::kSquare
@ kSquare
impeller::LinearPathComponent
Definition: path_component.h:28
impeller::Path::GetQuadraticComponentAtIndex
bool GetQuadraticComponentAtIndex(size_t index, QuadraticPathComponent &quadratic) const
Definition: path.cc:186
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Path::Clone
Path Clone() const
Deeply clone this path and all data associated with it.
Definition: path.cc:76
impeller::Path::PolylineContour
Definition: path.h:64
impeller::FillType::kOdd
@ kOdd
impeller::Path::ComponentType::kLinear
@ kLinear
impeller::Path::PolylineContour::start_index
size_t start_index
Index that denotes the first point of this contour.
Definition: path.h:74
impeller::Path::PolylineContour::components
std::vector< Component > components
Definition: path.h:89
impeller::FillType::kAbsGeqTwo
@ kAbsGeqTwo
impeller::Path::ComponentType::kCubic
@ kCubic
impeller::PathBuilder
Definition: path_builder.h:14
impeller::Path::GetBoundingBox
std::optional< Rect > GetBoundingBox() const
Definition: path.cc:388
impeller::Convexity
Convexity
Definition: path.h:38
impeller::Path::GetMinMaxCoveragePoints
std::optional< std::pair< Point, Point > > GetMinMaxCoveragePoints() const
Definition: path.cc:413
impeller::Path::ComponentType::kQuadratic
@ kQuadratic
impeller::Cap::kButt
@ kButt
impeller::Path::Polyline::Polyline
Polyline(PointBufferPtr point_buffer, ReclaimPointBufferCallback reclaim)
Definition: path.cc:234
impeller::FillType::kPositive
@ kPositive
impeller::Join::kMiter
@ kMiter
impeller::Path::~Path
~Path()
impeller::Path::Polyline
Definition: path.h:98
impeller::Convexity::kUnknown
@ kUnknown
impeller::Path::ComponentType
ComponentType
Definition: path.h:57
impeller::Path::GetCubicComponentAtIndex
bool GetCubicComponentAtIndex(size_t index, CubicPathComponent &cubic) const
Definition: path.cc:203
impeller::Path::Polyline::ReclaimPointBufferCallback
std::function< void(PointBufferPtr)> ReclaimPointBufferCallback
Definition: path.h:102
impeller::Path::EnumerateComponents
void EnumerateComponents(const Applier< LinearPathComponent > &linear_applier, const Applier< QuadraticPathComponent > &quad_applier, const Applier< CubicPathComponent > &cubic_applier, const Applier< ContourComponent > &contour_applier) const
Definition: path.cc:129
impeller::Path::PolylineContour::start_direction
Vector2 start_direction
The direction of the contour's start cap.
Definition: path.h:81
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:55
impeller::Path::Polyline::GetPoint
Point & GetPoint(size_t index) const
Definition: path.h:115
impeller::Path::GetTransformedBoundingBox
std::optional< Rect > GetTransformedBoundingBox(const Matrix &transform) const
Definition: path.cc:404
impeller::Path::Polyline::GetContourPointBounds
std::tuple< size_t, size_t > GetContourPointBounds(size_t contour_index) const
Definition: path.cc:22
impeller::Path::PolylineContour::Component
Definition: path.h:65
impeller::FillType
FillType
Definition: path.h:30
impeller::Join::kRound
@ kRound
impeller::Path::PolylineContour::end_direction
Vector2 end_direction
The direction of the contour's end cap.
Definition: path.h:83
impeller::FillType::kNonZero
@ kNonZero
impeller::Path::Path
Path()
Definition: path.cc:16
impeller::Path::GetContourComponentAtIndex
bool GetContourComponentAtIndex(size_t index, ContourComponent &contour) const
Definition: path.cc:220
impeller::CubicPathComponent
Definition: path_component.h:94
impeller::Path::Polyline::points
PointBufferPtr points
Definition: path.h:113
impeller::Join::kBevel
@ kBevel
impeller::Path::PolylineContour::Component::is_curve
bool is_curve
Definition: path.h:71
impeller::Join
Join
Definition: path.h:24
impeller::Path::Applier
std::function< void(size_t index, const T &component)> Applier
Definition: path.h:148
impeller::TPoint< Scalar >
impeller::Path::GetComponentCount
size_t GetComponentCount(std::optional< ComponentType > type={}) const
Definition: path.cc:34
impeller::Path::Polyline::contours
std::vector< PolylineContour > contours
Definition: path.h:119
impeller::Path::Polyline::PointBufferPtr
std::unique_ptr< std::vector< Point > > PointBufferPtr
Definition: path.h:101
impeller::Path::Polyline::~Polyline
~Polyline()
Definition: path.cc:246
impeller::Path::IsConvex
bool IsConvex() const
Definition: path.cc:59
impeller::FillType::kNegative
@ kNegative
path_component.h
impeller::ContourComponent
Definition: path_component.h:146
impeller::Convexity::kConvex
@ kConvex
impeller::Path::PolylineContour::Component::component_start_index
size_t component_start_index
Definition: path.h:66
impeller
Definition: aiks_context.cc:10
impeller::QuadraticPathComponent
Definition: path_component.h:52
impeller::Path::CreatePolyline
Polyline CreatePolyline(Scalar scale, Polyline::PointBufferPtr point_buffer=std::make_unique< std::vector< Point >>(), Polyline::ReclaimPointBufferCallback reclaim=nullptr) const
Definition: path.cc:253
impeller::Path::GetLinearComponentAtIndex
bool GetLinearComponentAtIndex(size_t index, LinearPathComponent &linear) const
Definition: path.cc:171
impeller::Path::ComponentType::kContour
@ kContour
impeller::TRect
Definition: rect.h:22
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Path::PolylineContour::is_closed
bool is_closed
Definition: path.h:78
impeller::Cap
Cap
Definition: path.h:18
impeller::Path::GetFillType
FillType GetFillType() const
Definition: path.cc:55