Flutter Engine
 
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_.getFillType());
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), SafeNarrow(x2),
70 SafeNarrow(y2));
71 resetVolatility();
72}
73
75 double y1,
76 double x2,
77 double y2) {
78 sk_path_.rQuadTo(SafeNarrow(x1), SafeNarrow(y1), SafeNarrow(x2),
79 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), SafeNarrow(x2),
90 SafeNarrow(y2), SafeNarrow(x3), SafeNarrow(y3));
91 resetVolatility();
92}
93
95 double y1,
96 double x2,
97 double y2,
98 double x3,
99 double y3) {
100 sk_path_.rCubicTo(SafeNarrow(x1), SafeNarrow(y1), SafeNarrow(x2),
101 SafeNarrow(y2), SafeNarrow(x3), SafeNarrow(y3));
102 resetVolatility();
103}
104
105void CanvasPath::conicTo(double x1, double y1, double x2, double y2, double w) {
106 sk_path_.conicTo(SafeNarrow(x1), SafeNarrow(y1), SafeNarrow(x2),
107 SafeNarrow(y2), SafeNarrow(w));
108 resetVolatility();
109}
110
112 double y1,
113 double x2,
114 double y2,
115 double w) {
116 sk_path_.rConicTo(SafeNarrow(x1), SafeNarrow(y1), SafeNarrow(x2),
117 SafeNarrow(y2), SafeNarrow(w));
118 resetVolatility();
119}
120
121void CanvasPath::arcTo(double left,
122 double top,
123 double right,
124 double bottom,
125 double startAngle,
126 double sweepAngle,
127 bool forceMoveTo) {
128 sk_path_.arcTo(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top),
129 SafeNarrow(right), SafeNarrow(bottom)),
130 SafeNarrow(startAngle) * 180.0f / static_cast<float>(M_PI),
131 SafeNarrow(sweepAngle) * 180.0f / static_cast<float>(M_PI),
132 forceMoveTo);
133 resetVolatility();
134}
135
136void CanvasPath::arcToPoint(double arcEndX,
137 double arcEndY,
138 double radiusX,
139 double radiusY,
140 double xAxisRotation,
141 bool isLargeArc,
142 bool isClockwiseDirection) {
143 const auto arcSize = isLargeArc ? SkPath::ArcSize::kLarge_ArcSize
144 : SkPath::ArcSize::kSmall_ArcSize;
145 const auto direction =
146 isClockwiseDirection ? SkPathDirection::kCW : SkPathDirection::kCCW;
147
148 sk_path_.arcTo(SafeNarrow(radiusX), SafeNarrow(radiusY),
149 SafeNarrow(xAxisRotation), arcSize, direction,
150 SafeNarrow(arcEndX), SafeNarrow(arcEndY));
151 resetVolatility();
152}
153
154void CanvasPath::relativeArcToPoint(double arcEndDeltaX,
155 double arcEndDeltaY,
156 double radiusX,
157 double radiusY,
158 double xAxisRotation,
159 bool isLargeArc,
160 bool isClockwiseDirection) {
161 const auto arcSize = isLargeArc ? SkPath::ArcSize::kLarge_ArcSize
162 : SkPath::ArcSize::kSmall_ArcSize;
163 const auto direction =
164 isClockwiseDirection ? SkPathDirection::kCW : SkPathDirection::kCCW;
165 sk_path_.rArcTo(SafeNarrow(radiusX), SafeNarrow(radiusY),
166 SafeNarrow(xAxisRotation), arcSize, direction,
167 SafeNarrow(arcEndDeltaX), SafeNarrow(arcEndDeltaY));
168 resetVolatility();
169}
170
171void CanvasPath::addRect(double left, double top, double right, double bottom) {
172 sk_path_.addRect(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top),
173 SafeNarrow(right), SafeNarrow(bottom)));
174 resetVolatility();
175}
176
177void CanvasPath::addOval(double left, double top, double right, double bottom) {
178 sk_path_.addOval(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top),
179 SafeNarrow(right), SafeNarrow(bottom)));
180 resetVolatility();
181}
182
183void CanvasPath::addArc(double left,
184 double top,
185 double right,
186 double bottom,
187 double startAngle,
188 double sweepAngle) {
189 sk_path_.addArc(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top),
190 SafeNarrow(right), SafeNarrow(bottom)),
191 SafeNarrow(startAngle) * 180.0f / static_cast<float>(M_PI),
192 SafeNarrow(sweepAngle) * 180.0f / static_cast<float>(M_PI));
193 resetVolatility();
194}
195
196void CanvasPath::addPolygon(const tonic::Float32List& points, bool close) {
197 SkSpan<const SkPoint> ptsSpan = {
198 reinterpret_cast<const SkPoint*>(points.data()),
199 points.num_elements() / 2};
200 sk_path_.addPoly(ptsSpan, close);
201 resetVolatility();
202}
203
204void CanvasPath::addRRect(const RRect& rrect) {
205 sk_path_.addRRect(ToSkRRect(rrect.rrect));
206 resetVolatility();
207}
208
209void CanvasPath::addRSuperellipse(const RSuperellipse* rsuperellipse) {
210 DlPathBuilder builder;
212 rsuperellipse->bounds(), rsuperellipse->radii()));
213 sk_path_.addPath(builder.TakePath().GetSkPath(), SkPath::kAppend_AddPathMode);
214
215 resetVolatility();
216}
217
218void CanvasPath::addPath(CanvasPath* path, double dx, double dy) {
219 if (!path) {
220 Dart_ThrowException(ToDart("Path.addPath called with non-genuine Path."));
221 return;
222 }
223 sk_path_.addPath(path->sk_path_, SafeNarrow(dx), SafeNarrow(dy),
224 SkPath::kAppend_AddPathMode);
225 resetVolatility();
226}
227
229 double dx,
230 double dy,
231 Dart_Handle matrix4_handle) {
232 tonic::Float64List matrix4(matrix4_handle);
233
234 if (!path) {
235 matrix4.Release();
236 Dart_ThrowException(
237 ToDart("Path.addPathWithMatrix called with non-genuine Path."));
238 return;
239 }
240
241 SkMatrix matrix = ToSkMatrix(matrix4);
242 matrix4.Release();
243 matrix.setTranslateX(matrix.getTranslateX() + SafeNarrow(dx));
244 matrix.setTranslateY(matrix.getTranslateY() + SafeNarrow(dy));
245 sk_path_.addPath(path->sk_path_, matrix, SkPath::kAppend_AddPathMode);
246 resetVolatility();
247}
248
249void CanvasPath::extendWithPath(CanvasPath* path, double dx, double dy) {
250 if (!path) {
251 Dart_ThrowException(
252 ToDart("Path.extendWithPath called with non-genuine Path."));
253 return;
254 }
255 sk_path_.addPath(path->sk_path_, SafeNarrow(dx), SafeNarrow(dy),
256 SkPath::kExtend_AddPathMode);
257 resetVolatility();
258}
259
261 double dx,
262 double dy,
263 Dart_Handle matrix4_handle) {
264 tonic::Float64List matrix4(matrix4_handle);
265
266 if (!path) {
267 matrix4.Release();
268 Dart_ThrowException(
269 ToDart("Path.addPathWithMatrix called with non-genuine Path."));
270 return;
271 }
272
273 SkMatrix matrix = ToSkMatrix(matrix4);
274 matrix4.Release();
275 matrix.setTranslateX(matrix.getTranslateX() + SafeNarrow(dx));
276 matrix.setTranslateY(matrix.getTranslateY() + SafeNarrow(dy));
277 sk_path_.addPath(path->sk_path_, matrix, SkPath::kExtend_AddPathMode);
278 resetVolatility();
279}
280
282 sk_path_.close();
283 resetVolatility();
284}
285
287 sk_path_.reset();
288 resetVolatility();
289}
290
291bool CanvasPath::contains(double x, double y) {
292 return sk_path_.contains(SafeNarrow(x), SafeNarrow(y));
293}
294
295void CanvasPath::shift(Dart_Handle path_handle, double dx, double dy) {
296 fml::RefPtr<CanvasPath> path = Create(path_handle);
297 auto& other_mutable_path = path->sk_path_;
298 sk_path_.offset(SafeNarrow(dx), SafeNarrow(dy), &other_mutable_path);
299 resetVolatility();
300}
301
302void CanvasPath::transform(Dart_Handle path_handle,
303 Dart_Handle matrix4_handle) {
304 tonic::Float64List matrix4(matrix4_handle);
305 auto sk_matrix = ToSkMatrix(matrix4);
306 matrix4.Release();
307 fml::RefPtr<CanvasPath> path = Create(path_handle);
308 auto& other_mutable_path = path->sk_path_;
309 sk_path_.transform(sk_matrix, &other_mutable_path);
310}
311
312tonic::Float32List CanvasPath::getBounds() {
313 tonic::Float32List rect(Dart_NewTypedData(Dart_TypedData_kFloat32, 4));
314 const SkRect& bounds = sk_path_.getBounds();
315 rect[0] = bounds.left();
316 rect[1] = bounds.top();
317 rect[2] = bounds.right();
318 rect[3] = bounds.bottom();
319 return rect;
320}
321
322bool CanvasPath::op(CanvasPath* path1, CanvasPath* path2, int operation) {
323 bool result = Op(path1->sk_path_, path2->sk_path_,
324 static_cast<SkPathOp>(operation), &sk_path_);
325 resetVolatility();
326 return result;
327}
328
329void CanvasPath::clone(Dart_Handle path_handle) {
330 fml::RefPtr<CanvasPath> path = Create(path_handle);
331 // per Skia docs, this will create a fast copy
332 // data is shared until the source path or dest path are mutated
333 path->sk_path_ = this->sk_path_;
334}
335
336const DlPath& CanvasPath::path() const {
337 if (!dl_path_.has_value()) {
338 dl_path_.emplace(sk_path_);
339 }
340 return dl_path_.value();
341}
342
343} // namespace flutter
void moveTo(double x, double y)
Definition path.cc:48
tonic::Float32List getBounds()
Definition path.cc:312
void shift(Dart_Handle path_handle, double dx, double dy)
Definition path.cc:295
static fml::RefPtr< CanvasPath > Create(Dart_Handle wrapper)
Definition path.h:31
const DlPath & path() const
Definition path.cc:336
void relativeLineTo(double x, double y)
Definition path.cc:63
void clone(Dart_Handle path_handle)
Definition path.cc:329
void addRect(double left, double top, double right, double bottom)
Definition path.cc:171
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:154
void conicTo(double x1, double y1, double x2, double y2, double w)
Definition path.cc:105
void addPathWithMatrix(CanvasPath *path, double dx, double dy, Dart_Handle matrix4_handle)
Definition path.cc:228
bool contains(double x, double y)
Definition path.cc:291
void addRSuperellipse(const RSuperellipse *rse)
Definition path.cc:209
void addArc(double left, double top, double right, double bottom, double startAngle, double sweepAngle)
Definition path.cc:183
void relativeConicTo(double x1, double y1, double x2, double y2, double w)
Definition path.cc:111
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:322
void arcToPoint(double arcEndX, double arcEndY, double radiusX, double radiusY, double xAxisRotation, bool isLargeArc, bool isClockwiseDirection)
Definition path.cc:136
void extendWithPath(CanvasPath *path, double dx, double dy)
Definition path.cc:249
void relativeCubicTo(double x1, double y1, double x2, double y2, double x3, double y3)
Definition path.cc:94
void addPolygon(const tonic::Float32List &points, bool close)
Definition path.cc:196
void addPath(CanvasPath *path, double dx, double dy)
Definition path.cc:218
void extendWithPathAndMatrix(CanvasPath *path, double dx, double dy, Dart_Handle matrix4_handle)
Definition path.cc:260
void addRRect(const RRect &rrect)
Definition path.cc:204
~CanvasPath() override
void setFillType(int fill_type)
Definition path.cc:43
void transform(Dart_Handle path_handle, Dart_Handle matrix4_handle)
Definition path.cc:302
void addOval(double left, double top, double right, double bottom)
Definition path.cc:177
void arcTo(double left, double top, double right, double bottom, double startAngle, double sweepAngle, bool forceMoveTo)
Definition path.cc:121
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(SkPath *one, SkPath *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