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 
11 
12 namespace impeller {
13 
14 class PathBuilder {
15  public:
16  /// Used for approximating quarter circle arcs with cubic curves. This is the
17  /// control point distance which results in the smallest possible unit circle
18  /// integration for a right angle arc. It can be used to approximate arcs less
19  /// than 90 degrees to great effect by simply reducing it proportionally to
20  /// the angle. However, accuracy rapidly diminishes if magnified for obtuse
21  /// angle arcs, and so multiple cubic curves should be used when approximating
22  /// arcs greater than 90 degrees.
23  constexpr static const Scalar kArcApproximationMagic = 0.551915024494f;
24 
25  PathBuilder();
26 
27  ~PathBuilder();
28 
30 
32 
33  /// @brief Reserve [point_size] points and [verb_size] verbs in the underlying
34  /// path buffer.
35  void Reserve(size_t point_size, size_t verb_size);
36 
38 
39  PathBuilder& MoveTo(Point point, bool relative = false);
40 
41  PathBuilder& Close();
42 
43  /// @brief Insert a line from the current position to `point`.
44  ///
45  /// If `relative` is true, then `point` is relative to the current location.
46  PathBuilder& LineTo(Point point, bool relative = false);
47 
48  PathBuilder& HorizontalLineTo(Scalar x, bool relative = false);
49 
50  PathBuilder& VerticalLineTo(Scalar y, bool relative = false);
51 
52  /// @brief Insert a quadradic curve from the current position to `point` using
53  /// the control point `controlPoint`.
54  ///
55  /// If `relative` is true the `point` and `controlPoint` are relative to
56  /// current location.
57  PathBuilder& QuadraticCurveTo(Point controlPoint,
58  Point point,
59  bool relative = false);
60 
61  /// @brief Insert a cubic curve from the curren position to `point` using the
62  /// control points `controlPoint1` and `controlPoint2`.
63  ///
64  /// If `relative` is true the `point`, `controlPoint1`, and `controlPoint2`
65  /// are relative to current location.
66  PathBuilder& CubicCurveTo(Point controlPoint1,
67  Point controlPoint2,
68  Point point,
69  bool relative = false);
70 
71  PathBuilder& AddRect(Rect rect);
72 
73  PathBuilder& AddCircle(const Point& center, Scalar radius);
74 
75  PathBuilder& AddArc(const Rect& oval_bounds,
76  Radians start,
77  Radians sweep,
78  bool use_center = false);
79 
80  PathBuilder& AddOval(const Rect& rect);
81 
82  /// @brief Move to point `p1`, then insert a line from `p1` to `p2`.
83  PathBuilder& AddLine(const Point& p1, const Point& p2);
84 
85  /// @brief Move to point `p1`, then insert a quadradic curve from `p1` to `p2`
86  /// with the control point `cp`.
88 
89  /// @brief Move to point `p1`, then insert a cubic curve from `p1` to `p2`
90  /// with control points `cp1` and `cp2`.
91  PathBuilder& AddCubicCurve(Point p1, Point cp1, Point cp2, Point p2);
92 
93  /// @brief Transform the existing path segments and contours by the given
94  /// `offset`.
96 
97  /// @brief Set the bounding box that will be used by `Path.GetBoundingBox` in
98  /// place of performing the computation.
99  ///
100  /// When Impeller recieves Skia Path objects, many of these already
101  /// have computed bounds. This method is used to avoid needlessly
102  /// recomputing these bounds.
103  PathBuilder& SetBounds(Rect bounds);
104 
105  struct RoundingRadii {
110 
111  RoundingRadii() = default;
112 
113  RoundingRadii(Scalar p_top_left,
114  Scalar p_bottom_left,
115  Scalar p_top_right,
116  Scalar p_bottom_right)
117  : top_left(p_top_left, p_top_left),
118  bottom_left(p_bottom_left, p_bottom_left),
119  top_right(p_top_right, p_top_right),
120  bottom_right(p_bottom_right, p_bottom_right) {}
121 
122  explicit RoundingRadii(Scalar radius)
123  : top_left(radius, radius),
124  bottom_left(radius, radius),
125  top_right(radius, radius),
126  bottom_right(radius, radius) {}
127 
128  explicit RoundingRadii(Point radii)
129  : top_left(radii),
130  bottom_left(radii),
131  top_right(radii),
132  bottom_right(radii) {}
133 
134  explicit RoundingRadii(Size radii)
135  : top_left(radii),
136  bottom_left(radii),
137  top_right(radii),
138  bottom_right(radii) {}
139 
140  bool AreAllZero() const {
141  return top_left.IsZero() && //
142  bottom_left.IsZero() && //
143  top_right.IsZero() && //
145  }
146  };
147 
148  PathBuilder& AddRoundedRect(Rect rect, RoundingRadii radii);
149 
150  PathBuilder& AddRoundedRect(Rect rect, Size radii);
151 
152  PathBuilder& AddRoundedRect(Rect rect, Scalar radius);
153 
154  PathBuilder& AddPath(const Path& path);
155 
156  private:
157  Point subpath_start_;
158  Point current_;
159  Path::Data prototype_;
160 
161  PathBuilder& AddRoundedRectTopLeft(Rect rect, RoundingRadii radii);
162 
163  PathBuilder& AddRoundedRectTopRight(Rect rect, RoundingRadii radii);
164 
165  PathBuilder& AddRoundedRectBottomRight(Rect rect, RoundingRadii radii);
166 
167  PathBuilder& AddRoundedRectBottomLeft(Rect rect, RoundingRadii radii);
168 
169  void AddContourComponent(const Point& destination, bool is_closed = false);
170 
171  void SetContourClosed(bool is_closed);
172 
173  void AddLinearComponent(const Point& p1, const Point& p2);
174 
175  void AddQuadraticComponent(const Point& p1, const Point& cp, const Point& p2);
176 
177  void AddCubicComponent(const Point& p1,
178  const Point& cp1,
179  const Point& cp2,
180  const Point& p2);
181 
182  /// Compute the bounds of the path unless they are already computed or
183  /// set by an external source, such as |SetBounds|. Any call which mutates
184  /// the path data can invalidate the computed/set bounds.
185  void UpdateBounds();
186 
187  std::optional<std::pair<Point, Point>> GetMinMaxCoveragePoints() const;
188 
189  PathBuilder(const PathBuilder&) = delete;
190  PathBuilder& operator=(const PathBuilder&&) = delete;
191 };
192 
193 } // namespace impeller
194 
195 #endif // FLUTTER_IMPELLER_GEOMETRY_PATH_BUILDER_H_
path.h
impeller::PathBuilder::AddQuadraticCurve
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.
Definition: path_builder.cc:97
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::PathBuilder::SetBounds
PathBuilder & SetBounds(Rect bounds)
Set the bounding box that will be used by Path.GetBoundingBox in place of performing the computation.
Definition: path_builder.cc:453
impeller::PathBuilder::CubicCurveTo
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...
Definition: path_builder.cc:85
impeller::PathBuilder::AddPath
PathBuilder & AddPath(const Path &path)
Definition: path_builder.cc:425
impeller::PathBuilder
Definition: path_builder.h:14
impeller::Convexity
Convexity
Definition: path.h:34
impeller::PathBuilder::RoundingRadii::AreAllZero
bool AreAllZero() const
Definition: path_builder.h:140
impeller::PathBuilder::AddRoundedRect
PathBuilder & AddRoundedRect(Rect rect, RoundingRadii radii)
Definition: path_builder.cc:145
impeller::PathBuilder::HorizontalLineTo
PathBuilder & HorizontalLineTo(Scalar x, bool relative=false)
Definition: path_builder.cc:54
impeller::PathBuilder::~PathBuilder
~PathBuilder()
impeller::PathBuilder::SetConvexity
PathBuilder & SetConvexity(Convexity value)
Definition: path_builder.cc:80
impeller::PathBuilder::kArcApproximationMagic
constexpr static const Scalar kArcApproximationMagic
Definition: path_builder.h:23
impeller::PathBuilder::AddRect
PathBuilder & AddRect(Rect rect)
Definition: path_builder.cc:112
impeller::PathBuilder::RoundingRadii::bottom_right
Point bottom_right
Definition: path_builder.h:109
impeller::TPoint::IsZero
constexpr bool IsZero() const
Definition: point.h:234
impeller::PathBuilder::RoundingRadii
Definition: path_builder.h:105
impeller::TSize< Scalar >
impeller::PathBuilder::RoundingRadii::RoundingRadii
RoundingRadii()=default
impeller::PathBuilder::RoundingRadii::RoundingRadii
RoundingRadii(Scalar p_top_left, Scalar p_bottom_left, Scalar p_top_right, Scalar p_bottom_right)
Definition: path_builder.h:113
impeller::PathBuilder::Shift
PathBuilder & Shift(Point offset)
Transform the existing path segments and contours by the given offset.
Definition: path_builder.cc:442
impeller::PathBuilder::QuadraticCurveTo
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:70
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:51
impeller::PathBuilder::CopyPath
Path CopyPath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:17
impeller::PathBuilder::LineTo
PathBuilder & LineTo(Point point, bool relative=false)
Insert a line from the current position to point.
Definition: path_builder.cc:47
impeller::PathBuilder::AddCubicCurve
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.
Definition: path_builder.cc:103
impeller::PathBuilder::RoundingRadii::top_left
Point top_left
Definition: path_builder.h:106
impeller::Radians
Definition: scalar.h:38
impeller::FillType
FillType
Definition: path.h:29
impeller::PathBuilder::AddLine
PathBuilder & AddLine(const Point &p1, const Point &p2)
Move to point p1, then insert a line from p1 to p2.
Definition: path_builder.cc:419
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:22
impeller::FillType::kNonZero
@ kNonZero
impeller::PathBuilder::PathBuilder
PathBuilder()
Definition: path_builder.cc:11
scalar.h
impeller::PathBuilder::Reserve
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:28
impeller::PathBuilder::RoundingRadii::RoundingRadii
RoundingRadii(Size radii)
Definition: path_builder.h:134
impeller::PathBuilder::Close
PathBuilder & Close()
Definition: path_builder.cc:40
impeller::PathBuilder::RoundingRadii::top_right
Point top_right
Definition: path_builder.h:108
rect.h
impeller::TPoint< Scalar >
impeller::PathBuilder::MoveTo
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:33
impeller::PathBuilder::RoundingRadii::RoundingRadii
RoundingRadii(Scalar radius)
Definition: path_builder.h:122
impeller::PathBuilder::RoundingRadii::bottom_left
Point bottom_left
Definition: path_builder.h:107
impeller::PathBuilder::VerticalLineTo
PathBuilder & VerticalLineTo(Scalar y, bool relative=false)
Definition: path_builder.cc:62
impeller::PathBuilder::AddCircle
PathBuilder & AddCircle(const Point &center, Scalar radius)
Definition: path_builder.cc:130
impeller::PathBuilder::AddOval
PathBuilder & AddOval(const Rect &rect)
Definition: path_builder.cc:371
offset
Point offset
Definition: stroke_path_geometry.cc:300
impeller
Definition: aiks_blur_unittests.cc:20
impeller::PathBuilder::RoundingRadii::RoundingRadii
RoundingRadii(Point radii)
Definition: path_builder.h:128
impeller::TRect< Scalar >
impeller::PathBuilder::AddArc
PathBuilder & AddArc(const Rect &oval_bounds, Radians start, Radians sweep, bool use_center=false)
Definition: path_builder.cc:313