• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // ACE PC preivew.
8 #ifndef WINDOWS_PLATFORM
9 // It cannot be passed to the sub-include of math.h, so define it in gn.
10 #define _USE_MATH_DEFINES
11 #endif
12 
13 #include <math.h>
14 
15 #include "flutter/lib/ui/painting/matrix.h"
16 
17 namespace flutter {
18 
19 typedef CanvasPath Path;
20 
21 IMPLEMENT_WRAPPERTYPEINFO(ui, Path);
22 
23 #define FOR_EACH_BINDING(V)          \
24   V(Path, addArc)                    \
25   V(Path, addOval)                   \
26   V(Path, addPath)                   \
27   V(Path, addPolygon)                \
28   V(Path, addRect)                   \
29   V(Path, addRRect)                  \
30   V(Path, arcTo)                     \
31   V(Path, arcToPoint)                \
32   V(Path, close)                     \
33   V(Path, conicTo)                   \
34   V(Path, contains)                  \
35   V(Path, cubicTo)                   \
36   V(Path, extendWithPath)            \
37   V(Path, extendWithPathAndMatrix)   \
38   V(Path, getFillType)               \
39   V(Path, lineTo)                    \
40   V(Path, moveTo)                    \
41   V(Path, quadraticBezierTo)         \
42   V(Path, relativeArcToPoint)        \
43   V(Path, relativeConicTo)           \
44   V(Path, relativeCubicTo)           \
45   V(Path, relativeLineTo)            \
46   V(Path, relativeMoveTo)            \
47   V(Path, relativeQuadraticBezierTo) \
48   V(Path, reset)                     \
49   V(Path, setFillType)               \
50   V(Path, shift)                     \
51   V(Path, transform)                 \
52   V(Path, getBounds)                 \
53   V(Path, addPathWithMatrix)         \
54   V(Path, op)                        \
55   V(Path, clone)
56 
FOR_EACH_BINDING(DART_NATIVE_CALLBACK)57 FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
58 
59 void CanvasPath::RegisterNatives(tonic::DartLibraryNatives* natives) {}
60 
CanvasPath()61 CanvasPath::CanvasPath() {}
62 
~CanvasPath()63 CanvasPath::~CanvasPath() {}
64 
getFillType()65 int CanvasPath::getFillType() {
66   return path_.getFillType();
67 }
68 
setFillType(int fill_type)69 void CanvasPath::setFillType(int fill_type) {
70   path_.setFillType(static_cast<SkPath::FillType>(fill_type));
71 }
72 
moveTo(float x,float y)73 void CanvasPath::moveTo(float x, float y) {
74   path_.moveTo(x, y);
75 }
76 
relativeMoveTo(float x,float y)77 void CanvasPath::relativeMoveTo(float x, float y) {
78   path_.rMoveTo(x, y);
79 }
80 
lineTo(float x,float y)81 void CanvasPath::lineTo(float x, float y) {
82   path_.lineTo(x, y);
83 }
84 
relativeLineTo(float x,float y)85 void CanvasPath::relativeLineTo(float x, float y) {
86   path_.rLineTo(x, y);
87 }
88 
quadraticBezierTo(float x1,float y1,float x2,float y2)89 void CanvasPath::quadraticBezierTo(float x1, float y1, float x2, float y2) {
90   path_.quadTo(x1, y1, x2, y2);
91 }
92 
relativeQuadraticBezierTo(float x1,float y1,float x2,float y2)93 void CanvasPath::relativeQuadraticBezierTo(float x1,
94                                            float y1,
95                                            float x2,
96                                            float y2) {
97   path_.rQuadTo(x1, y1, x2, y2);
98 }
99 
cubicTo(float x1,float y1,float x2,float y2,float x3,float y3)100 void CanvasPath::cubicTo(float x1,
101                          float y1,
102                          float x2,
103                          float y2,
104                          float x3,
105                          float y3) {
106   path_.cubicTo(x1, y1, x2, y2, x3, y3);
107 }
108 
relativeCubicTo(float x1,float y1,float x2,float y2,float x3,float y3)109 void CanvasPath::relativeCubicTo(float x1,
110                                  float y1,
111                                  float x2,
112                                  float y2,
113                                  float x3,
114                                  float y3) {
115   path_.rCubicTo(x1, y1, x2, y2, x3, y3);
116 }
117 
conicTo(float x1,float y1,float x2,float y2,float w)118 void CanvasPath::conicTo(float x1, float y1, float x2, float y2, float w) {
119   path_.conicTo(x1, y1, x2, y2, w);
120 }
121 
relativeConicTo(float x1,float y1,float x2,float y2,float w)122 void CanvasPath::relativeConicTo(float x1,
123                                  float y1,
124                                  float x2,
125                                  float y2,
126                                  float w) {
127   path_.rConicTo(x1, y1, x2, y2, w);
128 }
129 
arcTo(float left,float top,float right,float bottom,float startAngle,float sweepAngle,bool forceMoveTo)130 void CanvasPath::arcTo(float left,
131                        float top,
132                        float right,
133                        float bottom,
134                        float startAngle,
135                        float sweepAngle,
136                        bool forceMoveTo) {
137   path_.arcTo(SkRect::MakeLTRB(left, top, right, bottom),
138               startAngle * 180.0 / M_PI, sweepAngle * 180.0 / M_PI,
139               forceMoveTo);
140 }
141 
arcToPoint(float arcEndX,float arcEndY,float radiusX,float radiusY,float xAxisRotation,bool isLargeArc,bool isClockwiseDirection)142 void CanvasPath::arcToPoint(float arcEndX,
143                             float arcEndY,
144                             float radiusX,
145                             float radiusY,
146                             float xAxisRotation,
147                             bool isLargeArc,
148                             bool isClockwiseDirection) {
149   const auto arcSize = isLargeArc ? SkPath::ArcSize::kLarge_ArcSize
150                                   : SkPath::ArcSize::kSmall_ArcSize;
151   const auto direction = isClockwiseDirection
152                              ? SkPath::Direction::kCW_Direction
153                              : SkPath::Direction::kCCW_Direction;
154 
155   path_.arcTo(radiusX, radiusY, xAxisRotation, arcSize, direction, arcEndX,
156               arcEndY);
157 }
158 
relativeArcToPoint(float arcEndDeltaX,float arcEndDeltaY,float radiusX,float radiusY,float xAxisRotation,bool isLargeArc,bool isClockwiseDirection)159 void CanvasPath::relativeArcToPoint(float arcEndDeltaX,
160                                     float arcEndDeltaY,
161                                     float radiusX,
162                                     float radiusY,
163                                     float xAxisRotation,
164                                     bool isLargeArc,
165                                     bool isClockwiseDirection) {
166   const auto arcSize = isLargeArc ? SkPath::ArcSize::kLarge_ArcSize
167                                   : SkPath::ArcSize::kSmall_ArcSize;
168   const auto direction = isClockwiseDirection
169                              ? SkPath::Direction::kCW_Direction
170                              : SkPath::Direction::kCCW_Direction;
171   path_.rArcTo(radiusX, radiusY, xAxisRotation, arcSize, direction,
172                arcEndDeltaX, arcEndDeltaY);
173 }
174 
addRect(float left,float top,float right,float bottom)175 void CanvasPath::addRect(float left, float top, float right, float bottom) {
176   path_.addRect(SkRect::MakeLTRB(left, top, right, bottom));
177 }
178 
addOval(float left,float top,float right,float bottom)179 void CanvasPath::addOval(float left, float top, float right, float bottom) {
180   path_.addOval(SkRect::MakeLTRB(left, top, right, bottom));
181 }
182 
addArc(float left,float top,float right,float bottom,float startAngle,float sweepAngle)183 void CanvasPath::addArc(float left,
184                         float top,
185                         float right,
186                         float bottom,
187                         float startAngle,
188                         float sweepAngle) {
189   path_.addArc(SkRect::MakeLTRB(left, top, right, bottom),
190                startAngle * 180.0 / M_PI, sweepAngle * 180.0 / M_PI);
191 }
192 
addPolygon(const tonic::Float32List & points,bool close)193 void CanvasPath::addPolygon(const tonic::Float32List& points, bool close) {
194   path_.addPoly(reinterpret_cast<const SkPoint*>(points.data()),
195                 points.size() / 2, close);
196 }
197 
addRRect(const RRect & rrect)198 void CanvasPath::addRRect(const RRect& rrect) {
199   path_.addRRect(rrect.sk_rrect);
200 }
201 
addPath(CanvasPath * path,double dx,double dy)202 void CanvasPath::addPath(CanvasPath* path, double dx, double dy) {
203   if (!path) {
204     FML_LOG(ERROR) << "Path.addPath called with non-genuine Path.";
205     return;
206   }
207   path_.addPath(path->path(), dx, dy, SkPath::kAppend_AddPathMode);
208 }
209 
addPathWithMatrix(CanvasPath * path,double dx,double dy,tonic::Float64List & matrix4)210 void CanvasPath::addPathWithMatrix(CanvasPath* path,
211                                    double dx,
212                                    double dy,
213                                    tonic::Float64List& matrix4) {
214   if (!path) {
215     FML_LOG(ERROR) << "Path.addPathWithMatrix called with non-genuine Path.";
216     return;
217   }
218   SkMatrix matrix = ToSkMatrix(matrix4);
219   matrix.setTranslateX(matrix.getTranslateX() + dx);
220   matrix.setTranslateY(matrix.getTranslateY() + dy);
221   path_.addPath(path->path(), matrix, SkPath::kAppend_AddPathMode);
222 }
223 
extendWithPath(CanvasPath * path,double dx,double dy)224 void CanvasPath::extendWithPath(CanvasPath* path, double dx, double dy) {
225   if (!path) {
226     FML_LOG(ERROR) << "Path.extendWithPath called with non-genuine Path.";
227     return;
228   }
229   path_.addPath(path->path(), dx, dy, SkPath::kExtend_AddPathMode);
230 }
231 
extendWithPathAndMatrix(CanvasPath * path,double dx,double dy,tonic::Float64List & matrix4)232 void CanvasPath::extendWithPathAndMatrix(CanvasPath* path,
233                                          double dx,
234                                          double dy,
235                                          tonic::Float64List& matrix4) {
236   if (!path) {
237     FML_LOG(ERROR) << "Path.addPathWithMatrix called with non-genuine Path.";
238     return;
239   }
240 
241   SkMatrix matrix = ToSkMatrix(matrix4);
242   matrix.setTranslateX(matrix.getTranslateX() + dx);
243   matrix.setTranslateY(matrix.getTranslateY() + dy);
244   path_.addPath(path->path(), matrix, SkPath::kExtend_AddPathMode);
245 }
246 
close()247 void CanvasPath::close() {
248   path_.close();
249 }
250 
reset()251 void CanvasPath::reset() {
252   path_.reset();
253 }
254 
contains(double x,double y)255 bool CanvasPath::contains(double x, double y) {
256   return path_.contains(x, y);
257 }
258 
shift(double dx,double dy)259 fml::RefPtr<CanvasPath> CanvasPath::shift(double dx, double dy) {
260   fml::RefPtr<CanvasPath> path = CanvasPath::Create();
261   path_.offset(dx, dy, &path->path_);
262   return path;
263 }
264 
transform(tonic::Float64List & matrix4)265 fml::RefPtr<CanvasPath> CanvasPath::transform(tonic::Float64List& matrix4) {
266   fml::RefPtr<CanvasPath> path = CanvasPath::Create();
267   path_.transform(ToSkMatrix(matrix4), &path->path_);
268   return path;
269 }
270 
getBounds()271 tonic::Float32List CanvasPath::getBounds() {
272   tonic::Float32List rect(Dart_NewTypedData(Dart_TypedData_kFloat32, 4));
273   const SkRect& bounds = path_.getBounds();
274   rect[0] = bounds.left();
275   rect[1] = bounds.top();
276   rect[2] = bounds.right();
277   rect[3] = bounds.bottom();
278   return rect;
279 }
280 
op(CanvasPath * path1,CanvasPath * path2,int operation)281 bool CanvasPath::op(CanvasPath* path1, CanvasPath* path2, int operation) {
282   return Op(path1->path(), path2->path(), (SkPathOp)operation, &path_);
283 }
284 
clone()285 fml::RefPtr<CanvasPath> CanvasPath::clone() {
286   fml::RefPtr<CanvasPath> path = CanvasPath::Create();
287   // per Skia docs, this will create a fast copy
288   // data is shared until the source path or dest path are mutated
289   path->path_ = path_;
290   return path;
291 }
292 
293 }  // namespace flutter
294