Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
path.cc
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
6
7#include <cmath>
8
18
19using tonic::ToDart;
20
21namespace flutter {
22
23typedef CanvasPath Path;
24
26
27CanvasPath::CanvasPath() {
28 sk_path_.setIsVolatile(
29 !UIDartState::Current()->IsDeterministicRenderingEnabled());
30 resetVolatility();
31}
32
33CanvasPath::~CanvasPath() = default;
34
35void CanvasPath::resetVolatility() {
36 dl_path_.reset();
37}
38
40 return static_cast<int>(sk_path_.fillType());
41}
42
43void CanvasPath::setFillType(int fill_type) {
44 sk_path_.setFillType(static_cast<SkPathFillType>(fill_type));
45 resetVolatility();
46}
47
48void CanvasPath::moveTo(double x, double y) {
49 sk_path_.moveTo(SafeNarrow(x), SafeNarrow(y));
50 resetVolatility();
51}
52
53void CanvasPath::relativeMoveTo(double x, double y) {
54 sk_path_.rMoveTo({SafeNarrow(x), SafeNarrow(y)});
55 resetVolatility();
56}
57
58void CanvasPath::lineTo(double x, double y) {
59 sk_path_.lineTo({SafeNarrow(x), SafeNarrow(y)});
60 resetVolatility();
61}
62
63void CanvasPath::relativeLineTo(double x, double y) {
64 sk_path_.rLineTo({SafeNarrow(x), SafeNarrow(y)});
65 resetVolatility();
66}
67
68void CanvasPath::quadraticBezierTo(double x1, double y1, double x2, double y2) {
69 sk_path_.quadTo({SafeNarrow(x1), SafeNarrow(y1)},
70 {SafeNarrow(x2), SafeNarrow(y2)});
71 resetVolatility();
72}
73
75 double y1,
76 double x2,
77 double y2) {
78 sk_path_.rQuadTo({SafeNarrow(x1), SafeNarrow(y1)},
79 {SafeNarrow(x2), SafeNarrow(y2)});
80 resetVolatility();
81}
82
83void CanvasPath::cubicTo(double x1,
84 double y1,
85 double x2,
86 double y2,
87 double x3,
88 double y3) {
89 sk_path_.cubicTo({SafeNarrow(x1), SafeNarrow(y1)},
90 {SafeNarrow(x2), SafeNarrow(y2)},
91 {SafeNarrow(x3), SafeNarrow(y3)});
92 resetVolatility();
93}
94
96 double y1,
97 double x2,
98 double y2,
99 double x3,
100 double y3) {
101 sk_path_.rCubicTo({SafeNarrow(x1), SafeNarrow(y1)},
102 {SafeNarrow(x2), SafeNarrow(y2)},
103 {SafeNarrow(x3), SafeNarrow(y3)});
104 resetVolatility();
105}
106
107void CanvasPath::conicTo(double x1, double y1, double x2, double y2, double w) {
108 sk_path_.conicTo({SafeNarrow(x1), SafeNarrow(y1)},
109 {SafeNarrow(x2), SafeNarrow(y2)}, SafeNarrow(w));
110 resetVolatility();
111}
112
114 double y1,
115 double x2,
116 double y2,
117 double w) {
118 sk_path_.rConicTo({SafeNarrow(x1), SafeNarrow(y1)},
119 {SafeNarrow(x2), SafeNarrow(y2)}, SafeNarrow(w));
120 resetVolatility();
121}
122
123void CanvasPath::arcTo(double left,
124 double top,
125 double right,
126 double bottom,
127 double startAngle,
128 double sweepAngle,
129 bool forceMoveTo) {
130 sk_path_.arcTo(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top),
131 SafeNarrow(right), SafeNarrow(bottom)),
132 SafeNarrow(startAngle) * 180.0f / static_cast<float>(M_PI),
133 SafeNarrow(sweepAngle) * 180.0f / static_cast<float>(M_PI),
134 forceMoveTo);
135 resetVolatility();
136}
137
138void CanvasPath::arcToPoint(double arcEndX,
139 double arcEndY,
140 double radiusX,
141 double radiusY,
142 double xAxisRotation,
143 bool isLargeArc,
144 bool isClockwiseDirection) {
145 const auto arcSize = isLargeArc ? SkPathBuilder::ArcSize::kLarge_ArcSize
146 : SkPathBuilder::ArcSize::kSmall_ArcSize;
147 const auto direction =
148 isClockwiseDirection ? SkPathDirection::kCW : SkPathDirection::kCCW;
149
150 sk_path_.arcTo({SafeNarrow(radiusX), SafeNarrow(radiusY)},
151 SafeNarrow(xAxisRotation), arcSize, direction,
152 {SafeNarrow(arcEndX), SafeNarrow(arcEndY)});
153 resetVolatility();
154}
155
156void CanvasPath::relativeArcToPoint(double arcEndDeltaX,
157 double arcEndDeltaY,
158 double radiusX,
159 double radiusY,
160 double xAxisRotation,
161 bool isLargeArc,
162 bool isClockwiseDirection) {
163 const auto arcSize = isLargeArc ? SkPathBuilder::ArcSize::kLarge_ArcSize
164 : SkPathBuilder::ArcSize::kSmall_ArcSize;
165 const auto direction =
166 isClockwiseDirection ? SkPathDirection::kCW : SkPathDirection::kCCW;
167 sk_path_.rArcTo({SafeNarrow(radiusX), SafeNarrow(radiusY)},
168 SafeNarrow(xAxisRotation), arcSize, direction,
169 {SafeNarrow(arcEndDeltaX), SafeNarrow(arcEndDeltaY)});
170 resetVolatility();
171}
172
173void CanvasPath::addRect(double left, double top, double right, double bottom) {
174 sk_path_.addRect(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top),
175 SafeNarrow(right), SafeNarrow(bottom)));
176 resetVolatility();
177}
178
179void CanvasPath::addOval(double left, double top, double right, double bottom) {
180 sk_path_.addOval(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top),
181 SafeNarrow(right), SafeNarrow(bottom)));
182 resetVolatility();
183}
184
185void CanvasPath::addArc(double left,
186 double top,
187 double right,
188 double bottom,
189 double startAngle,
190 double sweepAngle) {
191 sk_path_.addArc(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top),
192 SafeNarrow(right), SafeNarrow(bottom)),
193 SafeNarrow(startAngle) * 180.0f / static_cast<float>(M_PI),
194 SafeNarrow(sweepAngle) * 180.0f / static_cast<float>(M_PI));
195 resetVolatility();
196}
197
198void CanvasPath::addPolygon(const tonic::Float32List& points, bool close) {
199 SkSpan<const SkPoint> ptsSpan = {
200 reinterpret_cast<const SkPoint*>(points.data()),
201 points.num_elements() / 2};
202 sk_path_.addPolygon(ptsSpan, close);
203 resetVolatility();
204}
205
206void CanvasPath::addRRect(const RRect& rrect) {
207 sk_path_.addRRect(ToSkRRect(rrect.rrect));
208 resetVolatility();
209}
210
211void CanvasPath::addRSuperellipse(const RSuperellipse* rsuperellipse) {
212 DlPathBuilder builder;
214 rsuperellipse->bounds(), rsuperellipse->radii()));
215 sk_path_.addPath(builder.TakePath().GetSkPath(), SkPath::kAppend_AddPathMode);
216
217 resetVolatility();
218}
219
220void CanvasPath::addPath(CanvasPath* path, double dx, double dy) {
221 if (!path) {
222 Dart_ThrowException(ToDart("Path.addPath called with non-genuine Path."));
223 return;
224 }
225 sk_path_.addPath(path->path().GetSkPath(), SafeNarrow(dx), SafeNarrow(dy),
226 SkPath::kAppend_AddPathMode);
227 resetVolatility();
228}
229
231 double dx,
232 double dy,
233 Dart_Handle matrix4_handle) {
234 tonic::Float64List matrix4(matrix4_handle);
235
236 if (!path) {
237 matrix4.Release();
238 Dart_ThrowException(
239 ToDart("Path.addPathWithMatrix called with non-genuine Path."));
240 return;
241 }
242
243 SkMatrix matrix = ToSkMatrix(matrix4);
244 matrix4.Release();
245 matrix.setTranslateX(matrix.getTranslateX() + SafeNarrow(dx));
246 matrix.setTranslateY(matrix.getTranslateY() + SafeNarrow(dy));
247 sk_path_.addPath(path->path().GetSkPath(), matrix,
248 SkPath::kAppend_AddPathMode);
249 resetVolatility();
250}
251
252void CanvasPath::extendWithPath(CanvasPath* path, double dx, double dy) {
253 if (!path) {
254 Dart_ThrowException(
255 ToDart("Path.extendWithPath called with non-genuine Path."));
256 return;
257 }
258 sk_path_.addPath(path->path().GetSkPath(), SafeNarrow(dx), SafeNarrow(dy),
259 SkPath::kExtend_AddPathMode);
260 resetVolatility();
261}
262
264 double dx,
265 double dy,
266 Dart_Handle matrix4_handle) {
267 tonic::Float64List matrix4(matrix4_handle);
268
269 if (!path) {
270 matrix4.Release();
271 Dart_ThrowException(
272 ToDart("Path.addPathWithMatrix called with non-genuine Path."));
273 return;
274 }
275
276 SkMatrix matrix = ToSkMatrix(matrix4);
277 matrix4.Release();
278 matrix.setTranslateX(matrix.getTranslateX() + SafeNarrow(dx));
279 matrix.setTranslateY(matrix.getTranslateY() + SafeNarrow(dy));
280 sk_path_.addPath(path->path().GetSkPath(), matrix,
281 SkPath::kExtend_AddPathMode);
282 resetVolatility();
283}
284
286 sk_path_.close();
287 resetVolatility();
288}
289
291 sk_path_.reset();
292 resetVolatility();
293}
294
295bool CanvasPath::contains(double x, double y) {
296 return sk_path_.contains({SafeNarrow(x), SafeNarrow(y)});
297}
298
299void CanvasPath::shift(Dart_Handle path_handle, double dx, double dy) {
300 fml::RefPtr<CanvasPath> path = Create(path_handle);
301 path->sk_path_ = sk_path_;
302 path->sk_path_.offset(SafeNarrow(dx), SafeNarrow(dy));
303}
304
305void CanvasPath::transform(Dart_Handle path_handle,
306 Dart_Handle matrix4_handle) {
307 tonic::Float64List matrix4(matrix4_handle);
308 auto sk_matrix = ToSkMatrix(matrix4);
309 matrix4.Release();
310 fml::RefPtr<CanvasPath> path = Create(path_handle);
311 path->sk_path_ = sk_path_;
312 path->sk_path_.transform(sk_matrix);
313}
314
315tonic::Float32List CanvasPath::getBounds() {
316 tonic::Float32List rect(Dart_NewTypedData(Dart_TypedData_kFloat32, 4));
317 const SkRect& bounds = sk_path_.computeFiniteBounds().value_or(SkRect());
318 rect[0] = bounds.left();
319 rect[1] = bounds.top();
320 rect[2] = bounds.right();
321 rect[3] = bounds.bottom();
322 return rect;
323}
324
325bool CanvasPath::op(CanvasPath* path1, CanvasPath* path2, int operation) {
326 std::optional<SkPath> result =
327 Op(path1->path().GetSkPath(), path2->path().GetSkPath(),
328 static_cast<SkPathOp>(operation));
329 if (result) {
330 sk_path_ = result.value();
331 resetVolatility();
332 return true;
333 }
334 return false;
335}
336
337void CanvasPath::clone(Dart_Handle path_handle) {
338 fml::RefPtr<CanvasPath> path = Create(path_handle);
339 // per Skia docs, this will create a fast copy
340 // data is shared until the source path or dest path are mutated
341 path->sk_path_ = this->sk_path_;
342}
343
344const DlPath& CanvasPath::path() const {
345 if (!dl_path_.has_value()) {
346 dl_path_.emplace(sk_path_.snapshot());
347 }
348 return dl_path_.value();
349}
350
351} // namespace flutter
void moveTo(double x, double y)
Definition path.cc:48
tonic::Float32List getBounds()
Definition path.cc:315
void shift(Dart_Handle path_handle, double dx, double dy)
Definition path.cc:299
static fml::RefPtr< CanvasPath > Create(Dart_Handle wrapper)
Definition path.h:32
const DlPath & path() const
Definition path.cc:344
void relativeLineTo(double x, double y)
Definition path.cc:63
void clone(Dart_Handle path_handle)
Definition path.cc:337
void addRect(double left, double top, double right, double bottom)
Definition path.cc:173
void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2)
Definition path.cc:74
void relativeArcToPoint(double arcEndDeltaX, double arcEndDeltaY, double radiusX, double radiusY, double xAxisRotation, bool isLargeArc, bool isClockwiseDirection)
Definition path.cc:156
void conicTo(double x1, double y1, double x2, double y2, double w)
Definition path.cc:107
void addPathWithMatrix(CanvasPath *path, double dx, double dy, Dart_Handle matrix4_handle)
Definition path.cc:230
bool contains(double x, double y)
Definition path.cc:295
void addRSuperellipse(const RSuperellipse *rse)
Definition path.cc:211
void addArc(double left, double top, double right, double bottom, double startAngle, double sweepAngle)
Definition path.cc:185
void relativeConicTo(double x1, double y1, double x2, double y2, double w)
Definition path.cc:113
int getFillType()
Definition path.cc:39
void relativeMoveTo(double x, double y)
Definition path.cc:53
void lineTo(double x, double y)
Definition path.cc:58
void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3)
Definition path.cc:83
void quadraticBezierTo(double x1, double y1, double x2, double y2)
Definition path.cc:68
bool op(CanvasPath *path1, CanvasPath *path2, int operation)
Definition path.cc:325
void arcToPoint(double arcEndX, double arcEndY, double radiusX, double radiusY, double xAxisRotation, bool isLargeArc, bool isClockwiseDirection)
Definition path.cc:138
void extendWithPath(CanvasPath *path, double dx, double dy)
Definition path.cc:252
void relativeCubicTo(double x1, double y1, double x2, double y2, double x3, double y3)
Definition path.cc:95
void addPolygon(const tonic::Float32List &points, bool close)
Definition path.cc:198
void addPath(CanvasPath *path, double dx, double dy)
Definition path.cc:220
void extendWithPathAndMatrix(CanvasPath *path, double dx, double dy, Dart_Handle matrix4_handle)
Definition path.cc:263
void addRRect(const RRect &rrect)
Definition path.cc:206
~CanvasPath() override
void setFillType(int fill_type)
Definition path.cc:43
void transform(Dart_Handle path_handle, Dart_Handle matrix4_handle)
Definition path.cc:305
void addOval(double left, double top, double right, double bottom)
Definition path.cc:179
void arcTo(double left, double top, double right, double bottom, double startAngle, double sweepAngle, bool forceMoveTo)
Definition path.cc:123
DlPathBuilder & AddRoundSuperellipse(const DlRoundSuperellipse &rse)
Append a closed rounded super-ellipse contour to the path.
const DlPath TakePath()
Returns the path constructed by this path builder and resets its internal state to the default state ...
const SkPath & GetSkPath() const
Definition dl_path.cc:116
DlRoundRect rrect
Definition rrect.h:17
flutter::DlRect bounds() const
impeller::RoundingRadii radii() const
static UIDartState * Current()
#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName)
int32_t x
SkMatrix sk_matrix
double y
void Op(SkPathBuilder *one, SkPathBuilder *two, SkPathOp op)
Definition path_ops.cc:44
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switch_defs.h:52
SkMatrix ToSkMatrix(const DlMatrix &matrix)
static float SafeNarrow(double value)
const SkRRect ToSkRRect(const DlRoundRect &round_rect)
CanvasPath Path
Definition dart_ui.cc:54
Dart_Handle ToDart(const T &object)
static RoundSuperellipse MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
std::vector< Point > points