Flutter Impeller
path_component.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_COMPONENT_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_PATH_COMPONENT_H_
7 
8 #include <functional>
9 #include <optional>
10 #include <type_traits>
11 #include <vector>
12 
15 
16 namespace impeller {
17 
18 /// @brief An interface for generating a multi contour polyline as a triangle
19 /// strip.
20 class VertexWriter {
21  public:
22  virtual void EndContour() = 0;
23 
24  virtual void Write(Point point) = 0;
25 };
26 
27 /// @brief A vertex writer that generates a triangle fan and requires primitive
28 /// restart.
29 class FanVertexWriter : public VertexWriter {
30  public:
31  explicit FanVertexWriter(Point* point_buffer, uint16_t* index_buffer);
32 
34 
35  size_t GetIndexCount() const;
36 
37  void EndContour() override;
38 
39  void Write(Point point) override;
40 
41  private:
42  size_t count_ = 0;
43  size_t index_count_ = 0;
44  Point* point_buffer_ = nullptr;
45  uint16_t* index_buffer_ = nullptr;
46 };
47 
48 /// @brief A vertex writer that generates a triangle strip and requires
49 /// primitive restart.
51  public:
52  explicit StripVertexWriter(Point* point_buffer, uint16_t* index_buffer);
53 
55 
56  size_t GetIndexCount() const;
57 
58  void EndContour() override;
59 
60  void Write(Point point) override;
61 
62  private:
63  size_t count_ = 0;
64  size_t index_count_ = 0;
65  size_t contour_start_ = 0;
66  Point* point_buffer_ = nullptr;
67  uint16_t* index_buffer_ = nullptr;
68 };
69 
70 /// @brief A vertex writer that generates a line strip topology.
72  public:
73  explicit LineStripVertexWriter(std::vector<Point>& points);
74 
76 
77  void EndContour() override;
78 
79  void Write(Point point) override;
80 
81  std::pair<size_t, size_t> GetVertexCount() const;
82 
83  const std::vector<Point>& GetOversizedBuffer() const;
84 
85  private:
86  size_t offset_ = 0u;
87  std::vector<Point>& points_;
88  std::vector<Point> overflow_;
89 };
90 
91 /// @brief A vertex writer that has no hardware requirements.
93  public:
94  explicit GLESVertexWriter(std::vector<Point>& points,
95  std::vector<uint16_t>& indices);
96 
97  ~GLESVertexWriter() = default;
98 
99  void EndContour() override;
100 
101  void Write(Point point) override;
102 
103  private:
104  bool previous_contour_odd_points_ = false;
105  size_t contour_start_ = 0u;
106  std::vector<Point>& points_;
107  std::vector<uint16_t>& indices_;
108 };
109 
113 
115 
116  LinearPathComponent(Point ap1, Point ap2) : p1(ap1), p2(ap2) {}
117 
118  Point Solve(Scalar time) const;
119 
120  void AppendPolylinePoints(std::vector<Point>& points) const;
121 
122  std::vector<Point> Extrema() const;
123 
124  bool operator==(const LinearPathComponent& other) const {
125  return p1 == other.p1 && p2 == other.p2;
126  }
127 
128  std::optional<Vector2> GetStartDirection() const;
129 
130  std::optional<Vector2> GetEndDirection() const;
131 };
132 
133 // A component that represets a Quadratic Bézier curve.
135  // Start point.
137  // Control point.
139  // End point.
141 
143 
145  : p1(ap1), cp(acp), p2(ap2) {}
146 
147  Point Solve(Scalar time) const;
148 
149  Point SolveDerivative(Scalar time) const;
150 
151  void AppendPolylinePoints(Scalar scale_factor,
152  std::vector<Point>& points) const;
153 
154  using PointProc = std::function<void(const Point& point)>;
155 
156  void ToLinearPathComponents(Scalar scale_factor, const PointProc& proc) const;
157 
158  void ToLinearPathComponents(Scalar scale, VertexWriter& writer) const;
159 
160  size_t CountLinearPathComponents(Scalar scale) const;
161 
162  std::vector<Point> Extrema() const;
163 
164  bool operator==(const QuadraticPathComponent& other) const {
165  return p1 == other.p1 && cp == other.cp && p2 == other.p2;
166  }
167 
168  std::optional<Vector2> GetStartDirection() const;
169 
170  std::optional<Vector2> GetEndDirection() const;
171 };
172 
173 // A component that represets a Cubic Bézier curve.
175  // Start point.
177  // The first control point.
179  // The second control point.
181  // End point.
183 
185 
187  : p1(q.p1),
188  cp1(q.p1 + (q.cp - q.p1) * (2.0 / 3.0)),
189  cp2(q.p2 + (q.cp - q.p2) * (2.0 / 3.0)),
190  p2(q.p2) {}
191 
192  CubicPathComponent(Point ap1, Point acp1, Point acp2, Point ap2)
193  : p1(ap1), cp1(acp1), cp2(acp2), p2(ap2) {}
194 
195  Point Solve(Scalar time) const;
196 
197  Point SolveDerivative(Scalar time) const;
198 
199  void AppendPolylinePoints(Scalar scale, std::vector<Point>& points) const;
200 
201  std::vector<Point> Extrema() const;
202 
203  using PointProc = std::function<void(const Point& point)>;
204 
205  void ToLinearPathComponents(Scalar scale, const PointProc& proc) const;
206 
207  void ToLinearPathComponents(Scalar scale, VertexWriter& writer) const;
208 
209  size_t CountLinearPathComponents(Scalar scale) const;
210 
212 
213  bool operator==(const CubicPathComponent& other) const {
214  return p1 == other.p1 && cp1 == other.cp1 && cp2 == other.cp2 &&
215  p2 == other.p2;
216  }
217 
218  std::optional<Vector2> GetStartDirection() const;
219 
220  std::optional<Vector2> GetEndDirection() const;
221 
222  private:
223  QuadraticPathComponent Lower() const;
224 };
225 
228 
229  // 0, 0 for closed, anything else for open.
230  Point closed = Point(1, 1);
231 
233 
234  constexpr bool IsClosed() const { return closed == Point{0, 0}; }
235 
237  : destination(p), closed(closed) {}
238 
239  bool operator==(const ContourComponent& other) const {
240  return destination == other.destination && IsClosed() == other.IsClosed();
241  }
242 };
243 
247 
248 } // namespace impeller
249 
250 #endif // FLUTTER_IMPELLER_GEOMETRY_PATH_COMPONENT_H_
A vertex writer that generates a triangle fan and requires primitive restart.
void EndContour() override
size_t GetIndexCount() const
void Write(Point point) override
FanVertexWriter(Point *point_buffer, uint16_t *index_buffer)
A vertex writer that has no hardware requirements.
GLESVertexWriter(std::vector< Point > &points, std::vector< uint16_t > &indices)
void Write(Point point) override
A vertex writer that generates a line strip topology.
std::pair< size_t, size_t > GetVertexCount() const
LineStripVertexWriter(std::vector< Point > &points)
void Write(Point point) override
const std::vector< Point > & GetOversizedBuffer() const
A vertex writer that generates a triangle strip and requires primitive restart.
void Write(Point point) override
StripVertexWriter(Point *point_buffer, uint16_t *index_buffer)
An interface for generating a multi contour polyline as a triangle strip.
virtual void EndContour()=0
virtual void Write(Point point)=0
int32_t value
float Scalar
Definition: scalar.h:18
TPoint< Scalar > Point
Definition: point.h:327
const Scalar scale
bool operator==(const ContourComponent &other) const
constexpr bool IsClosed() const
ContourComponent(Point p, Point closed)
void ToLinearPathComponents(Scalar scale, const PointProc &proc) const
size_t CountLinearPathComponents(Scalar scale) const
void AppendPolylinePoints(Scalar scale, std::vector< Point > &points) const
CubicPathComponent(Point ap1, Point acp1, Point acp2, Point ap2)
bool operator==(const CubicPathComponent &other) const
std::function< void(const Point &point)> PointProc
CubicPathComponent Subsegment(Scalar t0, Scalar t1) const
Point Solve(Scalar time) const
std::optional< Vector2 > GetStartDirection() const
std::vector< Point > Extrema() const
std::optional< Vector2 > GetEndDirection() const
Point SolveDerivative(Scalar time) const
CubicPathComponent(const QuadraticPathComponent &q)
std::optional< Vector2 > GetEndDirection() const
LinearPathComponent(Point ap1, Point ap2)
std::optional< Vector2 > GetStartDirection() const
std::vector< Point > Extrema() const
bool operator==(const LinearPathComponent &other) const
Point Solve(Scalar time) const
void AppendPolylinePoints(std::vector< Point > &points) const
size_t CountLinearPathComponents(Scalar scale) const
std::optional< Vector2 > GetEndDirection() const
QuadraticPathComponent(Point ap1, Point acp, Point ap2)
void AppendPolylinePoints(Scalar scale_factor, std::vector< Point > &points) const
bool operator==(const QuadraticPathComponent &other) const
std::function< void(const Point &point)> PointProc
std::vector< Point > Extrema() const
Point SolveDerivative(Scalar time) const
std::optional< Vector2 > GetStartDirection() const
void ToLinearPathComponents(Scalar scale_factor, const PointProc &proc) const
Point Solve(Scalar time) const