Flutter Engine
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 
5 #include "flutter/lib/ui/painting/path.h"
6 
7 #include <cmath>
8 
9 #include "flutter/lib/ui/painting/matrix.h"
10 #include "flutter/lib/ui/ui_dart_state.h"
15 
16 using tonic::ToDart;
17 
18 namespace flutter {
19 
20 typedef CanvasPath Path;
21 
22 static void Path_constructor(Dart_NativeArguments args) {
25 }
26 
28 
29 #define FOR_EACH_BINDING(V) \
30  V(Path, addArc) \
31  V(Path, addOval) \
32  V(Path, addPath) \
33  V(Path, addPolygon) \
34  V(Path, addRect) \
35  V(Path, addRRect) \
36  V(Path, arcTo) \
37  V(Path, arcToPoint) \
38  V(Path, close) \
39  V(Path, conicTo) \
40  V(Path, contains) \
41  V(Path, cubicTo) \
42  V(Path, extendWithPath) \
43  V(Path, extendWithPathAndMatrix) \
44  V(Path, getFillType) \
45  V(Path, lineTo) \
46  V(Path, moveTo) \
47  V(Path, quadraticBezierTo) \
48  V(Path, relativeArcToPoint) \
49  V(Path, relativeConicTo) \
50  V(Path, relativeCubicTo) \
51  V(Path, relativeLineTo) \
52  V(Path, relativeMoveTo) \
53  V(Path, relativeQuadraticBezierTo) \
54  V(Path, reset) \
55  V(Path, setFillType) \
56  V(Path, shift) \
57  V(Path, transform) \
58  V(Path, getBounds) \
59  V(Path, addPathWithMatrix) \
60  V(Path, op) \
61  V(Path, clone)
62 
64 
65 void CanvasPath::RegisterNatives(tonic::DartLibraryNatives* natives) {
66  natives->Register({{"Path_constructor", Path_constructor, 1, true},
68 }
69 
70 CanvasPath::CanvasPath() {}
71 
73 
75  return static_cast<int>(path_.getFillType());
76 }
77 
78 void CanvasPath::setFillType(int fill_type) {
79  path_.setFillType(static_cast<SkPathFillType>(fill_type));
80 }
81 
82 void CanvasPath::moveTo(float x, float y) {
83  path_.moveTo(x, y);
84 }
85 
86 void CanvasPath::relativeMoveTo(float x, float y) {
87  path_.rMoveTo(x, y);
88 }
89 
90 void CanvasPath::lineTo(float x, float y) {
91  path_.lineTo(x, y);
92 }
93 
94 void CanvasPath::relativeLineTo(float x, float y) {
95  path_.rLineTo(x, y);
96 }
97 
98 void CanvasPath::quadraticBezierTo(float x1, float y1, float x2, float y2) {
99  path_.quadTo(x1, y1, x2, y2);
100 }
101 
103  float y1,
104  float x2,
105  float y2) {
106  path_.rQuadTo(x1, y1, x2, y2);
107 }
108 
109 void CanvasPath::cubicTo(float x1,
110  float y1,
111  float x2,
112  float y2,
113  float x3,
114  float y3) {
115  path_.cubicTo(x1, y1, x2, y2, x3, y3);
116 }
117 
119  float y1,
120  float x2,
121  float y2,
122  float x3,
123  float y3) {
124  path_.rCubicTo(x1, y1, x2, y2, x3, y3);
125 }
126 
127 void CanvasPath::conicTo(float x1, float y1, float x2, float y2, float w) {
128  path_.conicTo(x1, y1, x2, y2, w);
129 }
130 
132  float y1,
133  float x2,
134  float y2,
135  float w) {
136  path_.rConicTo(x1, y1, x2, y2, w);
137 }
138 
139 void CanvasPath::arcTo(float left,
140  float top,
141  float right,
142  float bottom,
143  float startAngle,
144  float sweepAngle,
145  bool forceMoveTo) {
146  path_.arcTo(SkRect::MakeLTRB(left, top, right, bottom),
147  startAngle * 180.0 / M_PI, sweepAngle * 180.0 / M_PI,
148  forceMoveTo);
149 }
150 
151 void CanvasPath::arcToPoint(float arcEndX,
152  float arcEndY,
153  float radiusX,
154  float radiusY,
155  float xAxisRotation,
156  bool isLargeArc,
157  bool isClockwiseDirection) {
158  const auto arcSize = isLargeArc ? SkPath::ArcSize::kLarge_ArcSize
159  : SkPath::ArcSize::kSmall_ArcSize;
160  const auto direction =
161  isClockwiseDirection ? SkPathDirection::kCW : SkPathDirection::kCCW;
162 
163  path_.arcTo(radiusX, radiusY, xAxisRotation, arcSize, direction, arcEndX,
164  arcEndY);
165 }
166 
167 void CanvasPath::relativeArcToPoint(float arcEndDeltaX,
168  float arcEndDeltaY,
169  float radiusX,
170  float radiusY,
171  float xAxisRotation,
172  bool isLargeArc,
173  bool isClockwiseDirection) {
174  const auto arcSize = isLargeArc ? SkPath::ArcSize::kLarge_ArcSize
175  : SkPath::ArcSize::kSmall_ArcSize;
176  const auto direction =
177  isClockwiseDirection ? SkPathDirection::kCW : SkPathDirection::kCCW;
178  path_.rArcTo(radiusX, radiusY, xAxisRotation, arcSize, direction,
179  arcEndDeltaX, arcEndDeltaY);
180 }
181 
182 void CanvasPath::addRect(float left, float top, float right, float bottom) {
183  path_.addRect(SkRect::MakeLTRB(left, top, right, bottom));
184 }
185 
186 void CanvasPath::addOval(float left, float top, float right, float bottom) {
187  path_.addOval(SkRect::MakeLTRB(left, top, right, bottom));
188 }
189 
190 void CanvasPath::addArc(float left,
191  float top,
192  float right,
193  float bottom,
194  float startAngle,
195  float sweepAngle) {
196  path_.addArc(SkRect::MakeLTRB(left, top, right, bottom),
197  startAngle * 180.0 / M_PI, sweepAngle * 180.0 / M_PI);
198 }
199 
200 void CanvasPath::addPolygon(const tonic::Float32List& points, bool close) {
201  path_.addPoly(reinterpret_cast<const SkPoint*>(points.data()),
202  points.num_elements() / 2, close);
203 }
204 
205 void CanvasPath::addRRect(const RRect& rrect) {
206  path_.addRRect(rrect.sk_rrect);
207 }
208 
209 void CanvasPath::addPath(CanvasPath* path, double dx, double dy) {
210  if (!path) {
211  Dart_ThrowException(ToDart("Path.addPath called with non-genuine Path."));
212  return;
213  }
214  path_.addPath(path->path(), dx, dy, SkPath::kAppend_AddPathMode);
215 }
216 
218  double dx,
219  double dy,
220  tonic::Float64List& matrix4) {
221  if (!path) {
222  Dart_ThrowException(
223  ToDart("Path.addPathWithMatrix called with non-genuine Path."));
224  return;
225  }
226 
227  SkMatrix matrix = ToSkMatrix(matrix4);
228  matrix.setTranslateX(matrix.getTranslateX() + dx);
229  matrix.setTranslateY(matrix.getTranslateY() + dy);
230  path_.addPath(path->path(), matrix, SkPath::kAppend_AddPathMode);
231  matrix4.Release();
232 }
233 
234 void CanvasPath::extendWithPath(CanvasPath* path, double dx, double dy) {
235  if (!path) {
236  Dart_ThrowException(
237  ToDart("Path.extendWithPath called with non-genuine Path."));
238  return;
239  }
240  path_.addPath(path->path(), dx, dy, SkPath::kExtend_AddPathMode);
241 }
242 
244  double dx,
245  double dy,
246  tonic::Float64List& matrix4) {
247  if (!path) {
248  Dart_ThrowException(
249  ToDart("Path.addPathWithMatrix called with non-genuine Path."));
250  return;
251  }
252 
253  SkMatrix matrix = ToSkMatrix(matrix4);
254  matrix.setTranslateX(matrix.getTranslateX() + dx);
255  matrix.setTranslateY(matrix.getTranslateY() + dy);
256  path_.addPath(path->path(), matrix, SkPath::kExtend_AddPathMode);
257  matrix4.Release();
258 }
259 
261  path_.close();
262 }
263 
265  path_.reset();
266 }
267 
268 bool CanvasPath::contains(double x, double y) {
269  return path_.contains(x, y);
270 }
271 
272 void CanvasPath::shift(Dart_Handle path_handle, double dx, double dy) {
274  path_.offset(dx, dy, &path->path_);
275 }
276 
277 void CanvasPath::transform(Dart_Handle path_handle,
278  tonic::Float64List& matrix4) {
280  path_.transform(ToSkMatrix(matrix4), &path->path_);
281  matrix4.Release();
282 }
283 
284 tonic::Float32List CanvasPath::getBounds() {
285  tonic::Float32List rect(Dart_NewTypedData(Dart_TypedData_kFloat32, 4));
286  const SkRect& bounds = path_.getBounds();
287  rect[0] = bounds.left();
288  rect[1] = bounds.top();
289  rect[2] = bounds.right();
290  rect[3] = bounds.bottom();
291  return rect;
292 }
293 
294 bool CanvasPath::op(CanvasPath* path1, CanvasPath* path2, int operation) {
295  return Op(path1->path(), path2->path(), static_cast<SkPathOp>(operation),
296  &path_);
297 }
298 
299 void CanvasPath::clone(Dart_Handle path_handle) {
301  // per Skia docs, this will create a fast copy
302  // data is shared until the source path or dest path are mutated
303  path->path_ = path_;
304 }
305 
306 // This is doomed to be called too early, since Paths are mutable.
307 // However, it can help for some of the clone/shift/transform type methods
308 // where the resultant path will initially have a meaningful size.
310  return sizeof(CanvasPath) + path_.approximateBytesUsed();
311 }
312 
313 } // namespace flutter
G_BEGIN_DECLS FlValue * args
SkRRect sk_rrect
Definition: rrect.h:16
void arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, bool forceMoveTo)
Definition: path.cc:139
static fml::RefPtr< CanvasPath > Create(Dart_Handle path_handle)
Definition: path.h:30
void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
Definition: path.cc:109
void moveTo(float x, float y)
Definition: path.cc:82
void DartCallConstructor(Sig func, Dart_NativeArguments args)
Definition: dart_args.h:218
void conicTo(float x1, float y1, float x2, float y2, float w)
Definition: path.cc:127
bool op(CanvasPath *path1, CanvasPath *path2, int operation)
Definition: path.cc:294
#define DART_NATIVE_CALLBACK(CLASS, METHOD)
static void Path_constructor(Dart_NativeArguments args)
Definition: path.cc:22
#define FOR_EACH_BINDING(V)
Definition: path.cc:29
void addPath(CanvasPath *path, double dx, double dy)
Definition: path.cc:209
void clone(Dart_Handle path_handle)
Definition: path.cc:299
size_t GetAllocationSize() const override
Definition: path.cc:309
void relativeConicTo(float x1, float y1, float x2, float y2, float w)
Definition: path.cc:131
void addOval(float left, float top, float right, float bottom)
Definition: path.cc:186
void extendWithPathAndMatrix(CanvasPath *path, double dx, double dy, tonic::Float64List &matrix4)
Definition: path.cc:243
void addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle)
Definition: path.cc:190
void lineTo(float x, float y)
Definition: path.cc:90
IMPLEMENT_WRAPPERTYPEINFO(ui, Scene)
const SkPath & path() const
Definition: path.h:111
void relativeCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
Definition: path.cc:118
void shift(Dart_Handle path_handle, double dx, double dy)
Definition: path.cc:272
static void ThrowIfUIOperationsProhibited()
void addRect(float left, float top, float right, float bottom)
Definition: path.cc:182
void addPathWithMatrix(CanvasPath *path, double dx, double dy, tonic::Float64List &matrix4)
Definition: path.cc:217
void arcToPoint(float arcEndX, float arcEndY, float radiusX, float radiusY, float xAxisRotation, bool isLargeArc, bool isClockwiseDirection)
Definition: path.cc:151
void relativeLineTo(float x, float y)
Definition: path.cc:94
int getFillType()
Definition: path.cc:74
void addPolygon(const tonic::Float32List &points, bool close)
Definition: path.cc:200
void extendWithPath(CanvasPath *path, double dx, double dy)
Definition: path.cc:234
void relativeArcToPoint(float arcEndDeltaX, float arcEndDeltaY, float radiusX, float radiusY, float xAxisRotation, bool isLargeArc, bool isClockwiseDirection)
Definition: path.cc:167
static fml::RefPtr< CanvasPath > CreateNew(Dart_Handle path_handle)
Definition: path.h:26
void setFillType(int fill_type)
Definition: path.cc:78
#define DART_REGISTER_NATIVE(CLASS, METHOD)
void quadraticBezierTo(float x1, float y1, float x2, float y2)
Definition: path.cc:98
void transform(Dart_Handle path_handle, tonic::Float64List &matrix4)
Definition: path.cc:277
Dart_Handle ToDart(const T &object)
void relativeQuadraticBezierTo(float x1, float y1, float x2, float y2)
Definition: path.cc:102
SkMatrix ToSkMatrix(const tonic::Float64List &matrix4)
Definition: matrix.cc:20
void relativeMoveTo(float x, float y)
Definition: path.cc:86
bool contains(double x, double y)
Definition: path.cc:268
void addRRect(const RRect &rrect)
Definition: path.cc:205
CanvasPath Path
Definition: path.cc:20
tonic::Float32List getBounds()
Definition: path.cc:284
~CanvasPath() override
Definition: path.cc:72