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