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