| 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
8 #include "impeller/geometry/path.h"
9 #include "impeller/geometry/rect.h"
10 #include "impeller/geometry/scalar.h"
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
29 Path CopyPath(FillType fill = FillType::kNonZero);
30
31 Path TakePath(FillType fill = FillType::kNonZero);
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
37 PathBuilder& SetConvexity(Convexity value);
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`.
87 PathBuilder& AddQuadraticCurve(Point p1, Point cp, Point p2);
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`.
95 PathBuilder& Shift(Point 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 {
106 Point top_left;
107 Point bottom_left;
108 Point top_right;
109 Point bottom_right;
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() && //
144 bottom_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 size_t current_contour_location_ = 0u;
160 Path::Data prototype_;
161
162 PathBuilder& AddRoundedRectTopLeft(Rect rect, RoundingRadii radii);
163
164 PathBuilder& AddRoundedRectTopRight(Rect rect, RoundingRadii radii);
165
166 PathBuilder& AddRoundedRectBottomRight(Rect rect, RoundingRadii radii);
167
168 PathBuilder& AddRoundedRectBottomLeft(Rect rect, RoundingRadii radii);
169
170 void AddContourComponent(const Point& destination, bool is_closed = false);
171
172 void SetContourClosed(bool is_closed);
173
174 void AddLinearComponent(const Point& p1, const Point& p2);
175
176 void AddQuadraticComponent(const Point& p1, const Point& cp, const Point& p2);
177
178 void AddCubicComponent(const Point& p1,
179 const Point& cp1,
180 const Point& cp2,
181 const Point& p2);
182
183 /// Compute the bounds of the path unless they are already computed or
184 /// set by an external source, such as |SetBounds|. Any call which mutates
185 /// the path data can invalidate the computed/set bounds.
186 void UpdateBounds();
187
188 std::optional<std::pair<Point, Point>> GetMinMaxCoveragePoints() const;
189
190 PathBuilder(const PathBuilder&) = delete;
191 PathBuilder& operator=(const PathBuilder&&) = delete;
192 };
193
194 } // namespace impeller
195
196 #endif // FLUTTER_IMPELLER_GEOMETRY_PATH_BUILDER_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:105
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:494
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:93
impeller::PathBuilder::AddPath
PathBuilder & AddPath(const Path &path)
Definition: path_builder.cc:435
impeller::PathBuilder
Definition: path_builder.h:14
impeller::Convexity
Convexity
Definition: path.h:35
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:153
impeller::PathBuilder::HorizontalLineTo
PathBuilder & HorizontalLineTo(Scalar x, bool relative=false)
Definition: path_builder.cc:62
impeller::PathBuilder::~PathBuilder
~PathBuilder()
impeller::PathBuilder::SetConvexity
PathBuilder & SetConvexity(Convexity value)
Definition: path_builder.cc:88
impeller::PathBuilder::kArcApproximationMagic
constexpr static const Scalar kArcApproximationMagic
Definition: path_builder.h:23
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:304
impeller::PathBuilder::AddRect
PathBuilder & AddRect(Rect rect)
Definition: path_builder.cc:120
impeller::PathBuilder::RoundingRadii::bottom_right
Point bottom_right
Definition: path_builder.h:109
impeller::TPoint::IsZero
constexpr bool IsZero() const
Definition: point.h:240
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:454
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:78
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:52
impeller::PathBuilder::CopyPath
Path CopyPath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:19
impeller::PathBuilder::LineTo
PathBuilder & LineTo(Point point, bool relative=false)
Insert a line from the current position to point.
Definition: path_builder.cc:55
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:111
impeller::PathBuilder::RoundingRadii::top_left
Point top_left
Definition: path_builder.h:106
impeller::Radians
Definition: scalar.h:43
impeller::FillType
FillType
Definition: path.h:30
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:429
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:24
impeller::FillType::kNonZero
@ kNonZero
impeller::PathBuilder::PathBuilder
PathBuilder()
Definition: path_builder.cc:13
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:31
impeller::PathBuilder::RoundingRadii::RoundingRadii
RoundingRadii(Size radii)
Definition: path_builder.h:134
impeller::PathBuilder::Close
PathBuilder & Close()
Definition: path_builder.cc:43
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:36
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:70
impeller::PathBuilder::AddCircle
PathBuilder & AddCircle(const Point &center, Scalar radius)
Definition: path_builder.cc:138
impeller::PathBuilder::AddOval
PathBuilder & AddOval(const Rect &rect)
Definition: path_builder.cc:381
path.h
impeller
Definition: allocation.cc:12
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:323