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 
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) {
65  return 2u;
67  return 3u;
69  return 4u;
71  return 2u;
72  break;
73  }
74  FML_UNREACHABLE();
75  }
76 
77  struct PolylineContour {
78  struct Component {
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.
95  /// The direction of the contour's end cap.
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|.
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 
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_
GLenum type
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:53
FillType GetFillType() const
Definition: path.cc:48
size_t GetComponentCount(std::optional< ComponentType > type={}) const
Definition: path.cc:34
bool GetContourComponentAtIndex(size_t index, ContourComponent &contour) const
Definition: path.cc:237
ComponentType GetComponentTypeAtIndex(size_t index) const
Definition: path.cc:173
Polyline CreatePolyline(Scalar scale, Polyline::PointBufferPtr point_buffer=std::make_unique< std::vector< Point >>(), Polyline::ReclaimPointBufferCallback reclaim=nullptr) const
Definition: path.cc:338
bool IsSingleContour() const
Whether the line contains a single contour.
Definition: path.cc:62
std::optional< Rect > GetTransformedBoundingBox(const Matrix &transform) const
Definition: path.cc:440
static constexpr size_t VerbToOffset(Path::ComponentType verb)
Definition: path.h:62
bool IsConvex() const
Definition: path.cc:52
bool GetLinearComponentAtIndex(size_t index, LinearPathComponent &linear) const
Definition: path.cc:178
void WritePolyline(Scalar scale, VertexWriter &writer) const
Definition: path.cc:105
bool IsEmpty() const
Definition: path.cc:56
bool GetQuadraticComponentAtIndex(size_t index, QuadraticPathComponent &quadratic) const
Definition: path.cc:196
void EndContour(size_t storage_offset, Polyline &polyline, size_t component_index, std::vector< PolylineContour::Component > &poly_components) const
Definition: path.cc:274
bool GetCubicComponentAtIndex(size_t index, CubicPathComponent &cubic) const
Definition: path.cc:217
std::optional< Rect > GetBoundingBox() const
Definition: path.cc:436
std::pair< size_t, size_t > CountStorage(Scalar scale) const
Determine required storage for points and number of contours.
Definition: path.cc:67
An interface for generating a multi contour polyline as a triangle strip.
Join
Definition: path.h:25
float Scalar
Definition: scalar.h:18
FillType
Definition: path.h:31
Convexity
Definition: path.h:36
Cap
Definition: path.h:19
const Scalar scale
const Path::Polyline & polyline
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
Vector2 start_direction
The direction of the contour's start cap.
Definition: path.h:94
size_t start_index
Index that denotes the first point of this contour.
Definition: path.h:87
std::vector< Component > components
Definition: path.h:102
Vector2 end_direction
The direction of the contour's end cap.
Definition: path.h:96
Polyline(PointBufferPtr point_buffer, ReclaimPointBufferCallback reclaim)
Definition: path.cc:255
std::vector< PolylineContour > contours
Definition: path.h:132
Point & GetPoint(size_t index) const
Definition: path.h:128
std::function< void(PointBufferPtr)> ReclaimPointBufferCallback
Definition: path.h:115
std::unique_ptr< std::vector< Point > > PointBufferPtr
Definition: path.h:114
PointBufferPtr points
Definition: path.h:126
std::tuple< size_t, size_t > GetContourPointBounds(size_t contour_index) const
Definition: path.cc:22
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:64