| 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 <tuple>
11 #include <vector>
12
13 #include "impeller/geometry/path_component.h"
14 #include "impeller/geometry/rect.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 };
34
35 enum class Convexity {
36 kUnknown,
37 kConvex,
38 };
39
40 //------------------------------------------------------------------------------
41 /// @brief Paths are lightweight objects that describe a collection of
42 /// linear, quadratic, or cubic segments. These segments may be
43 /// broken up by move commands, which are effectively linear
44 /// commands that pick up the pen rather than continuing to draw.
45 ///
46 /// All shapes supported by Impeller are paths either directly or
47 /// via approximation (in the case of circles).
48 ///
49 /// Paths are externally immutable once created, Creating paths must
50 /// be done using a path builder.
51 ///
52 class Path {
53 public:
54 enum class ComponentType {
55 kLinear,
56 kQuadratic,
57 kCubic,
58 kContour,
59 };
60
61 static constexpr size_t VerbToOffset(Path::ComponentType verb) {
62 switch (verb) {
63 case Path::ComponentType::kLinear:
64 return 2u;
65 case Path::ComponentType::kQuadratic:
66 return 3u;
67 case Path::ComponentType::kCubic:
68 return 4u;
69 case Path::ComponentType::kContour:
70 return 2u;
71 break;
72 }
73 FML_UNREACHABLE();
74 }
75
76 struct PolylineContour {
77 struct Component {
78 size_t component_start_index;
79 /// Denotes whether this component is a curve.
80 ///
81 /// This is set to true when this component is generated from
82 /// QuadraticComponent or CubicPathComponent.
83 bool is_curve;
84 };
85 /// Index that denotes the first point of this contour.
86 size_t start_index;
87
88 /// Denotes whether the last point of this contour is connected to the first
89 /// point of this contour or not.
90 bool is_closed;
91
92 /// The direction of the contour's start cap.
93 Vector2 start_direction;
94 /// The direction of the contour's end cap.
95 Vector2 end_direction;
96
97 /// Distinct components in this contour.
98 ///
99 /// If this contour is generated from multiple path components, each
100 /// path component forms a component in this vector.
101 std::vector<Component> components;
102 };
103
104 /// One or more contours represented as a series of points and indices in
105 /// the point vector representing the start of a new contour.
106 ///
107 /// Polylines are ephemeral and meant to be used by the tessellator. They do
108 /// not allocate their own point vectors to allow for optimizations around
109 /// allocation and reuse of arenas.
110 struct Polyline {
111 /// The signature of a method called when it is safe to reclaim the point
112 /// buffer provided to the constructor of this object.
113 using PointBufferPtr = std::unique_ptr<std::vector<Point>>;
114 using ReclaimPointBufferCallback = std::function<void(PointBufferPtr)>;
115
116 /// The buffer will be cleared and returned at the destruction of this
117 /// polyline.
118 Polyline(PointBufferPtr point_buffer, ReclaimPointBufferCallback reclaim);
119
120 Polyline(Polyline&& other);
121 ~Polyline();
122
123 /// Points in the polyline, which may represent multiple contours specified
124 /// by indices in |contours|.
125 PointBufferPtr points;
126
127 Point& GetPoint(size_t index) const { return (*points)[index]; }
128
129 /// Contours are disconnected pieces of a polyline, such as when a MoveTo
130 /// was issued on a PathBuilder.
131 std::vector<PolylineContour> contours;
132
133 /// Convenience method to compute the start (inclusive) and end (exclusive)
134 /// point of the given contour index.
135 ///
136 /// The contour_index parameter is clamped to contours.size().
137 std::tuple<size_t, size_t> GetContourPointBounds(
138 size_t contour_index) const;
139
140 private:
141 ReclaimPointBufferCallback reclaim_points_;
142 };
143
144 Path();
145
146 ~Path();
147
148 size_t GetComponentCount(std::optional<ComponentType> type = {}) const;
149
150 FillType GetFillType() const;
151
152 bool IsConvex() const;
153
154 bool IsEmpty() const;
155
156 bool GetLinearComponentAtIndex(size_t index,
157 LinearPathComponent& linear) const;
158
159 bool GetQuadraticComponentAtIndex(size_t index,
160 QuadraticPathComponent& quadratic) const;
161
162 bool GetCubicComponentAtIndex(size_t index, CubicPathComponent& cubic) const;
163
164 bool GetContourComponentAtIndex(size_t index,
165 ContourComponent& contour) const;
166
167 /// Callers must provide the scale factor for how this path will be
168 /// transformed.
169 ///
170 /// It is suitable to use the max basis length of the matrix used to transform
171 /// the path. If the provided scale is 0, curves will revert to straight
172 /// lines.
173 Polyline CreatePolyline(
174 Scalar scale,
175 Polyline::PointBufferPtr point_buffer =
176 std::make_unique<std::vector<Point>>(),
177 Polyline::ReclaimPointBufferCallback reclaim = nullptr) const;
178
179 void EndContour(
180 size_t storage_offset,
181 Polyline& polyline,
182 size_t component_index,
183 std::vector<PolylineContour::Component>& poly_components) const;
184
185 std::optional<Rect> GetBoundingBox() const;
186
187 std::optional<Rect> GetTransformedBoundingBox(const Matrix& transform) const;
188
189 /// Generate a polyline into the temporary storage held by the [writer].
190 ///
191 /// It is suitable to use the max basis length of the matrix used to transform
192 /// the path. If the provided scale is 0, curves will revert to straight
193 /// lines.
194 void WritePolyline(Scalar scale, VertexWriter& writer) const;
195
196 private:
197 friend class PathBuilder;
198
199 // All of the data for the path is stored in this structure which is
200 // held by a shared_ptr. Since they all share the structure, the
201 // copy constructor for Path is very cheap and we don't need to deal
202 // with shared pointers for Path fields and method arguments.
203 //
204 // PathBuilder also uses this structure to accumulate the path data
205 // but the Path constructor used in |TakePath()| will clone the
206 // structure to prevent sharing and future modifications within the
207 // builder from affecting the existing taken paths.
208 struct Data {
209 Data() = default;
210
211 Data(Data&& other) = default;
212
213 Data(const Data& other) = default;
214
215 ~Data() = default;
216
217 FillType fill = FillType::kNonZero;
218 Convexity convexity = Convexity::kUnknown;
219 std::optional<Rect> bounds;
220 std::vector<Point> points;
221 std::vector<ComponentType> components;
222 };
223
224 explicit Path(Data data);
225
226 std::shared_ptr<const Data> data_;
227 };
228
229 static_assert(sizeof(Path) == sizeof(std::shared_ptr<struct Anonymous>));
230
231 } // namespace impeller
232
233 #endif // FLUTTER_IMPELLER_GEOMETRY_PATH_H_
impeller::Cap::kRound
@ kRound
impeller::Cap::kSquare
@ kSquare
polyline
const Path::Polyline & polyline
Definition: stroke_path_geometry.cc:296
impeller::LinearPathComponent
Definition: path_component.h:38
impeller::Path::GetQuadraticComponentAtIndex
bool GetQuadraticComponentAtIndex(size_t index, QuadraticPathComponent &quadratic) const
Definition: path.cc:147
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Path::PolylineContour
Definition: path.h:76
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:86
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
impeller::Path::PolylineContour::components
std::vector< Component > components
Definition: path.h:101
impeller::Path::ComponentType::kCubic
@ kCubic
impeller::PathBuilder
Definition: path_builder.h:14
impeller::Path::GetBoundingBox
std::optional< Rect > GetBoundingBox() const
Definition: path.cc:387
impeller::Convexity
Convexity
Definition: path.h:35
impeller::Path::ComponentType::kQuadratic
@ kQuadratic
impeller::Path::IsEmpty
bool IsEmpty() const
Definition: path.cc:55
impeller::Cap::kButt
@ kButt
impeller::Path::Polyline::Polyline
Polyline(PointBufferPtr point_buffer, ReclaimPointBufferCallback reclaim)
Definition: path.cc:206
impeller::Join::kMiter
@ kMiter
impeller::Path::~Path
~Path()
impeller::Path::Polyline
Definition: path.h:110
impeller::Convexity::kUnknown
@ kUnknown
impeller::Path::WritePolyline
void WritePolyline(Scalar scale, VertexWriter &writer) const
Definition: path.cc:61
impeller::Path::ComponentType
ComponentType
Definition: path.h:54
impeller::Path::GetCubicComponentAtIndex
bool GetCubicComponentAtIndex(size_t index, CubicPathComponent &cubic) const
Definition: path.cc:168
impeller::Path::Polyline::ReclaimPointBufferCallback
std::function< void(PointBufferPtr)> ReclaimPointBufferCallback
Definition: path.h:114
impeller::Path::PolylineContour::start_direction
Vector2 start_direction
The direction of the contour's start cap.
Definition: path.h:93
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:52
impeller::Path::Polyline::GetPoint
Point & GetPoint(size_t index) const
Definition: path.h:127
impeller::Path::GetTransformedBoundingBox
std::optional< Rect > GetTransformedBoundingBox(const Matrix &transform) const
Definition: path.cc:391
impeller::Path::EndContour
void EndContour(size_t storage_offset, Polyline &polyline, size_t component_index, std::vector< PolylineContour::Component > &poly_components) const
Definition: path.cc:225
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:213
impeller::Path::Polyline::GetContourPointBounds
std::tuple< size_t, size_t > GetContourPointBounds(size_t contour_index) const
Definition: path.cc:21
type
GLenum type
Definition: blit_command_gles.cc:127
impeller::Path::PolylineContour::Component
Definition: path.h:77
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:95
impeller::FillType::kNonZero
@ kNonZero
impeller::Path::Path
Path()
Definition: path.cc:15
impeller::Path::GetContourComponentAtIndex
bool GetContourComponentAtIndex(size_t index, ContourComponent &contour) const
Definition: path.cc:188
impeller::CubicPathComponent
Definition: path_component.h:100
impeller::Path::Polyline::points
PointBufferPtr points
Definition: path.h:125
impeller::Join::kBevel
@ kBevel
impeller::VertexWriter
An interface for generating a multi contour polyline as a triangle strip.
Definition: path_component.h:20
impeller::Path::PolylineContour::Component::is_curve
bool is_curve
Definition: path.h:83
impeller::Join
Join
Definition: path.h:24
rect.h
impeller::TPoint< Scalar >
impeller::Path::GetComponentCount
size_t GetComponentCount(std::optional< ComponentType > type={}) const
Definition: path.cc:33
impeller::Path::Polyline::contours
std::vector< PolylineContour > contours
Definition: path.h:131
scale
const Scalar scale
Definition: stroke_path_geometry.cc:301
impeller::Path::VerbToOffset
static constexpr size_t VerbToOffset(Path::ComponentType verb)
Definition: path.h:61
impeller::Path::Polyline::PointBufferPtr
std::unique_ptr< std::vector< Point > > PointBufferPtr
Definition: path.h:113
impeller::Path::Polyline::~Polyline
~Polyline()
Definition: path.cc:218
impeller::Path::IsConvex
bool IsConvex() const
Definition: path.cc:51
path_component.h
impeller::ContourComponent
Definition: path_component.h:150
impeller::Convexity::kConvex
@ kConvex
impeller::Path::PolylineContour::Component::component_start_index
size_t component_start_index
Definition: path.h:78
impeller
Definition: allocation.cc:12
impeller::QuadraticPathComponent
Definition: path_component.h:62
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:289
impeller::Path::GetLinearComponentAtIndex
bool GetLinearComponentAtIndex(size_t index, LinearPathComponent &linear) const
Definition: path.cc:129
impeller::Path::ComponentType::kContour
@ kContour
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Path::PolylineContour::is_closed
bool is_closed
Definition: path.h:90
impeller::Cap
Cap
Definition: path.h:18
impeller::Path::GetFillType
FillType GetFillType() const
Definition: path.cc:47