Flutter Impeller
path_builder.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_BUILDER_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_PATH_BUILDER_H_
7 
12 
13 namespace impeller {
14 
15 class PathBuilder {
16  public:
17  /// Used for approximating quarter circle arcs with cubic curves. This is the
18  /// control point distance which results in the smallest possible unit circle
19  /// integration for a right angle arc. It can be used to approximate arcs less
20  /// than 90 degrees to great effect by simply reducing it proportionally to
21  /// the angle. However, accuracy rapidly diminishes if magnified for obtuse
22  /// angle arcs, and so multiple cubic curves should be used when approximating
23  /// arcs greater than 90 degrees.
24  constexpr static const Scalar kArcApproximationMagic = 0.551915024494f;
25 
26  PathBuilder();
27 
29 
31 
33 
34  /// @brief Reserve [point_size] points and [verb_size] verbs in the underlying
35  /// path buffer.
36  void Reserve(size_t point_size, size_t verb_size);
37 
39 
40  PathBuilder& MoveTo(Point point, bool relative = false);
41 
42  PathBuilder& Close();
43 
44  /// @brief Insert a line from the current position to `point`.
45  ///
46  /// If `relative` is true, then `point` is relative to the current location.
47  PathBuilder& LineTo(Point point, bool relative = false);
48 
49  PathBuilder& HorizontalLineTo(Scalar x, bool relative = false);
50 
51  PathBuilder& VerticalLineTo(Scalar y, bool relative = false);
52 
53  /// @brief Insert a quadradic curve from the current position to `point` using
54  /// the control point `controlPoint`.
55  ///
56  /// If `relative` is true the `point` and `controlPoint` are relative to
57  /// current location.
58  PathBuilder& QuadraticCurveTo(Point controlPoint,
59  Point point,
60  bool relative = false);
61 
62  /// @brief Insert a cubic curve from the curren position to `point` using the
63  /// control points `controlPoint1` and `controlPoint2`.
64  ///
65  /// If `relative` is true the `point`, `controlPoint1`, and `controlPoint2`
66  /// are relative to current location.
67  PathBuilder& CubicCurveTo(Point controlPoint1,
68  Point controlPoint2,
69  Point point,
70  bool relative = false);
71 
72  PathBuilder& AddRect(Rect rect);
73 
74  PathBuilder& AddCircle(const Point& center, Scalar radius);
75 
76  PathBuilder& AddArc(const Rect& oval_bounds,
77  Radians start,
78  Radians sweep,
79  bool use_center = false);
80 
81  PathBuilder& AddOval(const Rect& rect);
82 
83  /// @brief Move to point `p1`, then insert a line from `p1` to `p2`.
84  PathBuilder& AddLine(const Point& p1, const Point& p2);
85 
86  /// @brief Move to point `p1`, then insert a quadradic curve from `p1` to `p2`
87  /// with the control point `cp`.
89 
90  /// @brief Move to point `p1`, then insert a cubic curve from `p1` to `p2`
91  /// with control points `cp1` and `cp2`.
92  PathBuilder& AddCubicCurve(Point p1, Point cp1, Point cp2, Point p2);
93 
94  /// @brief Transform the existing path segments and contours by the given
95  /// `offset`.
97 
98  /// @brief Set the bounding box that will be used by `Path.GetBoundingBox` in
99  /// place of performing the computation.
100  ///
101  /// When Impeller recieves Skia Path objects, many of these already
102  /// have computed bounds. This method is used to avoid needlessly
103  /// recomputing these bounds.
104  PathBuilder& SetBounds(Rect bounds);
105 
107 
108  PathBuilder& AddPath(const Path& path);
109 
110  private:
111  Point subpath_start_;
112  Point current_;
113  size_t current_contour_location_ = 0u;
114  size_t contour_count_ = 0u;
115  Path::Data prototype_;
116 
117  PathBuilder& AddRoundedRectTopLeft(Rect rect, RoundingRadii radii);
118 
119  PathBuilder& AddRoundedRectTopRight(Rect rect, RoundingRadii radii);
120 
121  PathBuilder& AddRoundedRectBottomRight(Rect rect, RoundingRadii radii);
122 
123  PathBuilder& AddRoundedRectBottomLeft(Rect rect, RoundingRadii radii);
124 
125  void AddContourComponent(const Point& destination, bool is_closed = false);
126 
127  void SetContourClosed(bool is_closed);
128 
129  void AddLinearComponent(const Point& p1, const Point& p2);
130 
131  void AddLinearComponentIfNeeded(const Point& p1, const Point& p2);
132 
133  void AddQuadraticComponent(const Point& p1, const Point& cp, const Point& p2);
134 
135  void AddCubicComponent(const Point& p1,
136  const Point& cp1,
137  const Point& cp2,
138  const Point& p2);
139 
140  /// Compute the bounds of the path unless they are already computed or
141  /// set by an external source, such as |SetBounds|. Any call which mutates
142  /// the path data can invalidate the computed/set bounds.
143  void UpdateBounds();
144 
145  std::optional<std::pair<Point, Point>> GetMinMaxCoveragePoints() const;
146 
147  PathBuilder(const PathBuilder&) = delete;
148  PathBuilder& operator=(const PathBuilder&&) = delete;
149 };
150 
151 } // namespace impeller
152 
153 #endif // FLUTTER_IMPELLER_GEOMETRY_PATH_BUILDER_H_
PathBuilder & AddRect(Rect rect)
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:28
PathBuilder & AddArc(const Rect &oval_bounds, Radians start, Radians sweep, bool use_center=false)
PathBuilder & AddRoundRect(RoundRect rect)
PathBuilder & LineTo(Point point, bool relative=false)
Insert a line from the current position to point.
Definition: path_builder.cc:64
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:45
PathBuilder & SetBounds(Rect bounds)
Set the bounding box that will be used by Path.GetBoundingBox in place of performing the computation.
void Reserve(size_t point_size, size_t verb_size)
Reserve [point_size] points and [verb_size] verbs in the underlying path buffer.
Definition: path_builder.cc:40
PathBuilder & AddOval(const Rect &rect)
PathBuilder & AddCircle(const Point &center, Scalar radius)
PathBuilder & Close()
Definition: path_builder.cc:52
PathBuilder & AddPath(const Path &path)
Path CopyPath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:19
PathBuilder & VerticalLineTo(Scalar y, bool relative=false)
Definition: path_builder.cc:79
PathBuilder & Shift(Point offset)
Transform the existing path segments and contours by the given offset.
PathBuilder & AddLine(const Point &p1, const Point &p2)
Move to point p1, then insert a line from p1 to p2.
constexpr static const Scalar kArcApproximationMagic
Definition: path_builder.h:24
PathBuilder & AddQuadraticCurve(Point p1, Point cp, Point p2)
Move to point p1, then insert a quadradic curve from p1 to p2 with the control point cp.
PathBuilder & CubicCurveTo(Point controlPoint1, Point controlPoint2, Point point, bool relative=false)
Insert a cubic curve from the curren position to point using the control points controlPoint1 and con...
PathBuilder & AddCubicCurve(Point p1, Point cp1, Point cp2, Point p2)
Move to point p1, then insert a cubic curve from p1 to p2 with control points cp1 and cp2.
PathBuilder & HorizontalLineTo(Scalar x, bool relative=false)
Definition: path_builder.cc:71
PathBuilder & SetConvexity(Convexity value)
Definition: path_builder.cc:97
PathBuilder & QuadraticCurveTo(Point controlPoint, Point point, bool relative=false)
Insert a quadradic curve from the current position to point using the control point controlPoint.
Definition: path_builder.cc:87
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:53
int32_t value
int32_t x
float Scalar
Definition: scalar.h:18
FillType
Definition: path.h:31
Convexity
Definition: path.h:36
SeparatedVector2 offset