1 #pragma once
2 
3 #include <memory>
4 #include <utility>
5 #include <vector>
6 
7 #include <jsi/jsi.h>
8 
9 #include "JsiSkHostObjects.h"
10 #include "JsiSkMatrix.h"
11 #include "JsiSkPoint.h"
12 #include "JsiSkRRect.h"
13 #include "JsiSkRect.h"
14 
15 #pragma clang diagnostic push
16 #pragma clang diagnostic ignored "-Wdocumentation"
17 
18 #include "SkDashPathEffect.h"
19 #include "SkParsePath.h"
20 #include "SkPath.h"
21 #include "SkPathEffect.h"
22 #include "SkPathOps.h"
23 #include "SkPathTypes.h"
24 #include "SkPathUtils.h"
25 #include "SkString.h"
26 #include "SkStrokeRec.h"
27 #include "SkTextUtils.h"
28 #include "SkTrimPathEffect.h"
29 
30 #pragma clang diagnostic pop
31 
32 namespace RNSkia {
33 
34 namespace jsi = facebook::jsi;
35 
36 class JsiSkPath : public JsiSkWrappingSharedPtrHostObject<SkPath> {
37 
38 public:
JSI_HOST_FUNCTION(addPath)39   JSI_HOST_FUNCTION(addPath) {
40     auto src = JsiSkPath::fromValue(runtime, arguments[0]);
41     auto matrix =
42         count > 1 && !arguments[1].isUndefined() && !arguments[1].isNull()
43             ? JsiSkMatrix::fromValue(runtime, arguments[1])
44             : nullptr;
45     auto mode = count > 2 && arguments[2].isBool() && arguments[2].getBool()
46                     ? SkPath::kExtend_AddPathMode
47                     : SkPath::kAppend_AddPathMode;
48     if (matrix == nullptr) {
49       getObject()->addPath(*src, mode);
50     } else {
51       getObject()->addPath(*src, *matrix, mode);
52     }
53     return thisValue.getObject(runtime);
54   }
55 
JSI_HOST_FUNCTION(addArc)56   JSI_HOST_FUNCTION(addArc) {
57     auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
58     auto start = arguments[1].asNumber();
59     auto sweep = arguments[2].asNumber();
60     getObject()->addArc(*rect, start, sweep);
61     return thisValue.getObject(runtime);
62   }
63 
JSI_HOST_FUNCTION(addOval)64   JSI_HOST_FUNCTION(addOval) {
65     auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
66     auto direction = SkPathDirection::kCW;
67     if (count >= 2 && arguments[1].getBool()) {
68       direction = SkPathDirection::kCCW;
69     }
70     unsigned startIndex = count < 3 ? 0 : arguments[2].asNumber();
71     auto result = getObject()->addOval(*rect, direction, startIndex);
72     return thisValue.getObject(runtime);
73   }
74 
JSI_HOST_FUNCTION(addPoly)75   JSI_HOST_FUNCTION(addPoly) {
76     std::vector<SkPoint> points;
77     auto jsiPoints = arguments[0].asObject(runtime).asArray(runtime);
78     auto close = arguments[1].getBool();
79     auto pointsSize = jsiPoints.size(runtime);
80     points.reserve(pointsSize);
81     for (int i = 0; i < pointsSize; i++) {
82       std::shared_ptr<SkPoint> point = JsiSkPoint::fromValue(
83           runtime, jsiPoints.getValueAtIndex(runtime, i).asObject(runtime));
84       points.push_back(*point.get());
85     }
86     getObject()->addPoly(points.data(), static_cast<int>(points.size()), close);
87     return thisValue.getObject(runtime);
88   }
89 
JSI_HOST_FUNCTION(addRect)90   JSI_HOST_FUNCTION(addRect) {
91     auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
92     auto direction = SkPathDirection::kCW;
93     if (count >= 2 && arguments[1].getBool()) {
94       direction = SkPathDirection::kCCW;
95     }
96     getObject()->addRect(*rect, direction);
97     return jsi::Value::undefined();
98   }
99 
JSI_HOST_FUNCTION(addRRect)100   JSI_HOST_FUNCTION(addRRect) {
101     auto rrect = JsiSkRRect::fromValue(runtime, arguments[0]);
102     auto direction = SkPathDirection::kCW;
103     if (count >= 2 && arguments[1].getBool()) {
104       direction = SkPathDirection::kCCW;
105     }
106     getObject()->addRRect(*rrect, direction);
107     return thisValue.getObject(runtime);
108   }
109 
JSI_HOST_FUNCTION(arcToOval)110   JSI_HOST_FUNCTION(arcToOval) {
111     auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
112     auto start = arguments[1].asNumber();
113     auto sweep = arguments[2].asNumber();
114     auto forceMoveTo = arguments[3].getBool();
115     getObject()->arcTo(*rect, start, sweep, forceMoveTo);
116     return thisValue.getObject(runtime);
117   }
118 
JSI_HOST_FUNCTION(arcToRotated)119   JSI_HOST_FUNCTION(arcToRotated) {
120     auto rx = arguments[0].asNumber();
121     auto ry = arguments[1].asNumber();
122     auto xAxisRotate = arguments[2].asNumber();
123     auto useSmallArc = arguments[3].getBool();
124     auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize
125                                : SkPath::ArcSize::kLarge_ArcSize;
126     auto sweep =
127         arguments[4].getBool() ? SkPathDirection::kCCW : SkPathDirection::kCW;
128     auto x = arguments[5].asNumber();
129     auto y = arguments[6].asNumber();
130     getObject()->arcTo(rx, ry, xAxisRotate, arcSize, sweep, x, y);
131     return thisValue.getObject(runtime);
132   }
133 
JSI_HOST_FUNCTION(rArcTo)134   JSI_HOST_FUNCTION(rArcTo) {
135     auto rx = arguments[0].asNumber();
136     auto ry = arguments[1].asNumber();
137     auto xAxisRotate = arguments[2].asNumber();
138     auto useSmallArc = arguments[3].getBool();
139     auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize
140                                : SkPath::ArcSize::kLarge_ArcSize;
141     auto sweep =
142         arguments[4].getBool() ? SkPathDirection::kCCW : SkPathDirection::kCW;
143     auto x = arguments[5].asNumber();
144     auto y = arguments[6].asNumber();
145     getObject()->rArcTo(rx, ry, xAxisRotate, arcSize, sweep, x, y);
146     return thisValue.getObject(runtime);
147   }
148 
JSI_HOST_FUNCTION(arcToTangent)149   JSI_HOST_FUNCTION(arcToTangent) {
150     auto x1 = arguments[0].asNumber();
151     auto y1 = arguments[1].asNumber();
152     auto x2 = arguments[2].asNumber();
153     auto y2 = arguments[3].asNumber();
154     auto r = arguments[4].asNumber();
155     getObject()->arcTo(x1, y1, x2, y2, r);
156     return thisValue.getObject(runtime);
157   }
158 
JSI_HOST_FUNCTION(computeTightBounds)159   JSI_HOST_FUNCTION(computeTightBounds) {
160     auto result = getObject()->computeTightBounds();
161     return jsi::Object::createFromHostObject(
162         runtime, std::make_shared<JsiSkRect>(getContext(), std::move(result)));
163   }
164 
165   // TODO-API: Should this be a property?
JSI_HOST_FUNCTION(getBounds)166   JSI_HOST_FUNCTION(getBounds) {
167     auto result = getObject()->getBounds();
168     return jsi::Object::createFromHostObject(
169         runtime, std::make_shared<JsiSkRect>(getContext(), std::move(result)));
170   }
171 
JSI_HOST_FUNCTION(conicTo)172   JSI_HOST_FUNCTION(conicTo) {
173     auto x1 = arguments[0].asNumber();
174     auto y1 = arguments[1].asNumber();
175     auto x2 = arguments[2].asNumber();
176     auto y2 = arguments[3].asNumber();
177     auto w = arguments[4].asNumber();
178     getObject()->conicTo(x1, y1, x2, y2, w);
179     return thisValue.getObject(runtime);
180   }
181 
JSI_HOST_FUNCTION(rConicTo)182   JSI_HOST_FUNCTION(rConicTo) {
183     auto x1 = arguments[0].asNumber();
184     auto y1 = arguments[1].asNumber();
185     auto x2 = arguments[2].asNumber();
186     auto y2 = arguments[3].asNumber();
187     auto w = arguments[4].asNumber();
188     getObject()->rConicTo(x1, y1, x2, y2, w);
189     return thisValue.getObject(runtime);
190   }
191 
JSI_HOST_FUNCTION(contains)192   JSI_HOST_FUNCTION(contains) {
193     auto x = arguments[0].asNumber();
194     auto y = arguments[1].asNumber();
195     return jsi::Value(getObject()->contains(x, y));
196   }
197 
JSI_HOST_FUNCTION(dash)198   JSI_HOST_FUNCTION(dash) {
199     SkScalar on = arguments[0].asNumber();
200     SkScalar off = arguments[1].asNumber();
201     auto phase = arguments[2].asNumber();
202     SkScalar intervals[] = {on, off};
203     auto pe = SkDashPathEffect::Make(intervals, 2, phase);
204     if (!pe) {
205       // TODO: SkDebugf("Invalid args to dash()\n");
206       return jsi::Value(false);
207     }
208     SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
209     SkPath &path = *getObject();
210     // TODO: why we don't need to swap here? In trim() which is the same
211     // API, we need to swap
212     if (pe->filterPath(&path, path, &rec, nullptr)) {
213       return jsi::Value(true);
214     }
215     SkDebugf("Could not make dashed path\n");
216     return jsi::Value(false);
217   }
218 
JSI_HOST_FUNCTION(equals)219   JSI_HOST_FUNCTION(equals) {
220     auto p1 = JsiSkPath::fromValue(runtime, arguments[0]).get();
221     auto p2 = JsiSkPath::fromValue(runtime, arguments[1]).get();
222     return jsi::Value(p1 == p2);
223   }
224 
225   // TODO-API: Property?
JSI_HOST_FUNCTION(getFillType)226   JSI_HOST_FUNCTION(getFillType) {
227     auto fillType = getObject()->getFillType();
228     return jsi::Value(static_cast<int>(fillType));
229   }
230 
231   // TODO-API: Property?
JSI_HOST_FUNCTION(setFillType)232   JSI_HOST_FUNCTION(setFillType) {
233     auto ft = (SkPathFillType)arguments[0].asNumber();
234     getObject()->setFillType(ft);
235     return jsi::Value::undefined();
236   }
237 
238   // TODO-API: Property?
JSI_HOST_FUNCTION(setIsVolatile)239   JSI_HOST_FUNCTION(setIsVolatile) {
240     auto v = arguments[0].getBool();
241     getObject()->setIsVolatile(v);
242     return jsi::Value::undefined();
243   }
244 
JSI_HOST_FUNCTION(isVolatile)245   JSI_HOST_FUNCTION(isVolatile) {
246     return jsi::Value(getObject()->isVolatile());
247   }
248 
JSI_HOST_FUNCTION(transform)249   JSI_HOST_FUNCTION(transform) {
250     auto m3 = *JsiSkMatrix::fromValue(runtime, arguments[0]);
251     getObject()->transform(m3);
252     return jsi::Value::undefined();
253   }
254 
JSI_HOST_FUNCTION(stroke)255   JSI_HOST_FUNCTION(stroke) {
256     auto path = *getObject();
257     auto opts = arguments[0].asObject(runtime);
258     SkPaint p;
259     p.setStyle(SkPaint::kStroke_Style);
260 
261     auto jsiCap = opts.getProperty(runtime, "cap");
262     if (!jsiCap.isUndefined()) {
263       auto cap = (SkPaint::Cap)jsiCap.asNumber();
264       p.setStrokeCap(cap);
265     }
266 
267     auto jsiJoin = opts.getProperty(runtime, "join");
268     if (!jsiJoin.isUndefined()) {
269       auto join = (SkPaint::Join)jsiJoin.asNumber();
270       p.setStrokeJoin(join);
271     }
272 
273     auto jsiWidth = opts.getProperty(runtime, "width");
274     if (!jsiWidth.isUndefined()) {
275       auto width = jsiWidth.asNumber();
276       p.setStrokeWidth(width);
277     }
278 
279     auto jsiMiterLimit = opts.getProperty(runtime, "miter_limit");
280     if (!jsiMiterLimit.isUndefined()) {
281       auto miter_limit = opts.getProperty(runtime, "miter_limit").asNumber();
282       p.setStrokeMiter(miter_limit);
283     }
284 
285     auto jsiPrecision = opts.getProperty(runtime, "precision");
286     auto precision = jsiPrecision.isUndefined() ? 1 : jsiPrecision.asNumber();
287     auto result =
288         skpathutils::FillPathWithPaint(path, p, &path, nullptr, precision);
289     if (result) {
290       getObject()->swap(path);
291     }
292     return result ? thisValue.getObject(runtime) : jsi::Value::null();
293   }
294 
JSI_HOST_FUNCTION(trim)295   JSI_HOST_FUNCTION(trim) {
296     auto start = arguments[0].asNumber();
297     auto end = arguments[1].asNumber();
298     auto isComplement = arguments[2].getBool();
299     auto path = *getObject();
300     auto mode = isComplement ? SkTrimPathEffect::Mode::kInverted
301                              : SkTrimPathEffect::Mode::kNormal;
302     auto pe = SkTrimPathEffect::Make(start, end, mode);
303     if (!pe) {
304       // SkDebugf("Invalid args to trim(): startT and stopT must be in
305       // [0,1]\n");
306       return jsi::Value::null();
307     }
308     SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
309     if (pe->filterPath(&path, path, &rec, nullptr)) {
310       getObject()->swap(path);
311       return thisValue.getObject(runtime);
312     }
313     SkDebugf("Could not trim path\n");
314     return jsi::Value::null();
315   }
316 
JSI_HOST_FUNCTION(getPoint)317   JSI_HOST_FUNCTION(getPoint) {
318     auto index = arguments[0].asNumber();
319     auto point = getObject()->getPoint(index);
320     return jsi::Object::createFromHostObject(
321         runtime, std::make_shared<JsiSkPoint>(getContext(), point));
322   }
323 
JSI_HOST_FUNCTION(toSVGString)324   JSI_HOST_FUNCTION(toSVGString) {
325     SkPath path = *getObject();
326     auto s = SkParsePath::ToSVGString(path);
327     return jsi::String::createFromUtf8(runtime, s.c_str());
328   }
329 
JSI_HOST_FUNCTION(makeAsWinding)330   JSI_HOST_FUNCTION(makeAsWinding) {
331     SkPath out;
332     if (AsWinding(*getObject(), &out)) {
333       getObject()->swap(out);
334       return thisValue.getObject(runtime);
335     }
336     return jsi::Value::null();
337   }
338 
JSI_HOST_FUNCTION(isEmpty)339   JSI_HOST_FUNCTION(isEmpty) { return jsi::Value(getObject()->isEmpty()); }
340 
JSI_HOST_FUNCTION(offset)341   JSI_HOST_FUNCTION(offset) {
342     SkScalar dx = arguments[0].asNumber();
343     SkScalar dy = arguments[1].asNumber();
344     getObject()->offset(dx, dy);
345     return thisValue.getObject(runtime);
346   }
347 
JSI_HOST_FUNCTION(moveTo)348   JSI_HOST_FUNCTION(moveTo) {
349     SkScalar x = arguments[0].asNumber();
350     SkScalar y = arguments[1].asNumber();
351     getObject()->moveTo(x, y);
352     return thisValue.getObject(runtime);
353   }
354 
JSI_HOST_FUNCTION(rMoveTo)355   JSI_HOST_FUNCTION(rMoveTo) {
356     SkScalar x = arguments[0].asNumber();
357     SkScalar y = arguments[1].asNumber();
358     getObject()->rMoveTo(x, y);
359     return thisValue.getObject(runtime);
360   }
JSI_HOST_FUNCTION(lineTo)361   JSI_HOST_FUNCTION(lineTo) {
362     SkScalar x = arguments[0].asNumber();
363     SkScalar y = arguments[1].asNumber();
364     getObject()->lineTo(x, y);
365     return thisValue.getObject(runtime);
366   }
367 
JSI_HOST_FUNCTION(rLineTo)368   JSI_HOST_FUNCTION(rLineTo) {
369     SkScalar x = arguments[0].asNumber();
370     SkScalar y = arguments[1].asNumber();
371     getObject()->rLineTo(x, y);
372     return thisValue.getObject(runtime);
373   }
374 
JSI_HOST_FUNCTION(cubicTo)375   JSI_HOST_FUNCTION(cubicTo) {
376     auto x1 = arguments[0].asNumber();
377     auto y1 = arguments[1].asNumber();
378     auto x2 = arguments[2].asNumber();
379     auto y2 = arguments[3].asNumber();
380     auto x3 = arguments[4].asNumber();
381     auto y3 = arguments[5].asNumber();
382     getObject()->cubicTo(x1, y1, x2, y2, x3, y3);
383     return thisValue.getObject(runtime);
384   }
385 
JSI_HOST_FUNCTION(rCubicTo)386   JSI_HOST_FUNCTION(rCubicTo) {
387     auto x1 = arguments[0].asNumber();
388     auto y1 = arguments[1].asNumber();
389     auto x2 = arguments[2].asNumber();
390     auto y2 = arguments[3].asNumber();
391     auto x3 = arguments[4].asNumber();
392     auto y3 = arguments[5].asNumber();
393     getObject()->rCubicTo(x1, y1, x2, y2, x3, y3);
394     return thisValue.getObject(runtime);
395   }
396 
JSI_HOST_FUNCTION(reset)397   JSI_HOST_FUNCTION(reset) {
398     getObject()->reset();
399     return jsi::Value::undefined();
400   }
401 
JSI_HOST_FUNCTION(rewind)402   JSI_HOST_FUNCTION(rewind) {
403     getObject()->rewind();
404     return jsi::Value::undefined();
405   }
406 
JSI_HOST_FUNCTION(quadTo)407   JSI_HOST_FUNCTION(quadTo) {
408     auto x1 = arguments[0].asNumber();
409     auto y1 = arguments[1].asNumber();
410     auto x2 = arguments[2].asNumber();
411     auto y2 = arguments[3].asNumber();
412     getObject()->quadTo(x1, y1, x2, y2);
413     return jsi::Value::undefined();
414   }
415 
JSI_HOST_FUNCTION(rQuadTo)416   JSI_HOST_FUNCTION(rQuadTo) {
417     auto x1 = arguments[0].asNumber();
418     auto y1 = arguments[1].asNumber();
419     auto x2 = arguments[2].asNumber();
420     auto y2 = arguments[3].asNumber();
421     getObject()->rQuadTo(x1, y1, x2, y2);
422     return thisValue.getObject(runtime);
423   }
424 
JSI_HOST_FUNCTION(addCircle)425   JSI_HOST_FUNCTION(addCircle) {
426     auto x = arguments[0].asNumber();
427     auto y = arguments[1].asNumber();
428     auto r = arguments[2].asNumber();
429     getObject()->addCircle(x, y, r);
430     return thisValue.getObject(runtime);
431   }
432 
JSI_HOST_FUNCTION(getLastPt)433   JSI_HOST_FUNCTION(getLastPt) {
434     SkPoint last;
435     getObject()->getLastPt(&last);
436     auto point = jsi::Object(runtime);
437     point.setProperty(runtime, "x", static_cast<double>(last.fX));
438     point.setProperty(runtime, "y", static_cast<double>(last.fY));
439     return point;
440   }
441 
JSI_HOST_FUNCTION(close)442   JSI_HOST_FUNCTION(close) {
443     getObject()->close();
444     return jsi::Value::undefined();
445   }
446 
JSI_HOST_FUNCTION(simplify)447   JSI_HOST_FUNCTION(simplify) {
448     SkPath result;
449     if (Simplify(*getObject(), &result)) {
450       getObject()->swap(result);
451       return jsi::Value(true);
452     }
453     return jsi::Value(false);
454   }
455 
JSI_HOST_FUNCTION(countPoints)456   JSI_HOST_FUNCTION(countPoints) {
457     auto points = getObject()->countPoints();
458     return jsi::Value(points);
459   }
460 
JSI_HOST_FUNCTION(copy)461   JSI_HOST_FUNCTION(copy) {
462     const auto *path = getObject().get();
463     return jsi::Object::createFromHostObject(
464         runtime, std::make_shared<JsiSkPath>(getContext(), SkPath(*path)));
465   }
466 
JSI_HOST_FUNCTION(op)467   JSI_HOST_FUNCTION(op) {
468     auto path2 = JsiSkPath::fromValue(runtime, arguments[0]);
469     int pathOp = arguments[1].asNumber();
470     SkPath result;
471     if (Op(*getObject(), *path2, SkPathOp(pathOp), &result)) {
472       getObject()->swap(result);
473       return jsi::Value(true);
474     }
475     return jsi::Value(false);
476   }
477 
JSI_HOST_FUNCTION(isInterpolatable)478   JSI_HOST_FUNCTION(isInterpolatable) {
479     auto path2 = JsiSkPath::fromValue(runtime, arguments[0]);
480     return getObject()->isInterpolatable(*path2);
481   }
482 
JSI_HOST_FUNCTION(interpolate)483   JSI_HOST_FUNCTION(interpolate) {
484     auto path2 = JsiSkPath::fromValue(runtime, arguments[0]);
485     auto weight = arguments[1].asNumber();
486     SkPath result;
487     auto succeed = getObject()->interpolate(*path2, weight, &result);
488     if (!succeed) {
489       return nullptr;
490     }
491     return jsi::Object::createFromHostObject(
492         runtime, std::make_shared<JsiSkPath>(getContext(), std::move(result)));
493   }
494 
JSI_HOST_FUNCTION(toCmds)495   JSI_HOST_FUNCTION(toCmds) {
496     auto path = *getObject();
497     auto cmds = jsi::Array(runtime, path.countVerbs());
498     auto it = SkPath::Iter(path, false);
499     //                       { "Move", "Line", "Quad", "Conic", "Cubic",
500     //                       "Close", "Done" };
501     const int pointCount[] = {1, 1, 2, 2, 3, 0, 0};
502     const int cmdCount[] = {3, 3, 5, 6, 7, 1, 0};
503     SkPoint points[4];
504     SkPath::Verb verb;
505     auto k = 0;
506     while (SkPath::kDone_Verb != (verb = it.next(points))) {
507       auto verbVal = static_cast<int>(verb);
508       auto cmd = jsi::Array(runtime, cmdCount[verbVal]);
509       auto j = 0;
510       cmd.setValueAtIndex(runtime, j++, jsi::Value(verbVal));
511       for (int i = 0; i < pointCount[verbVal]; ++i) {
512         cmd.setValueAtIndex(runtime, j++,
513                             jsi::Value(static_cast<double>(points[1 + i].fX)));
514         cmd.setValueAtIndex(runtime, j++,
515                             jsi::Value(static_cast<double>(points[1 + i].fY)));
516       }
517       if (SkPath::kConic_Verb == verb) {
518         cmd.setValueAtIndex(runtime, j,
519                             jsi::Value(static_cast<double>(it.conicWeight())));
520       }
521       cmds.setValueAtIndex(runtime, k++, cmd);
522     }
523     return cmds;
524   }
525 
526   EXPORT_JSI_API_TYPENAME(JsiSkPath, "Path")
527 
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC (JsiSkPath,addPath),JSI_EXPORT_FUNC (JsiSkPath,addArc),JSI_EXPORT_FUNC (JsiSkPath,addOval),JSI_EXPORT_FUNC (JsiSkPath,addPoly),JSI_EXPORT_FUNC (JsiSkPath,addRect),JSI_EXPORT_FUNC (JsiSkPath,addRRect),JSI_EXPORT_FUNC (JsiSkPath,arcToOval),JSI_EXPORT_FUNC (JsiSkPath,arcToRotated),JSI_EXPORT_FUNC (JsiSkPath,rArcTo),JSI_EXPORT_FUNC (JsiSkPath,arcToTangent),JSI_EXPORT_FUNC (JsiSkPath,computeTightBounds),JSI_EXPORT_FUNC (JsiSkPath,getBounds),JSI_EXPORT_FUNC (JsiSkPath,conicTo),JSI_EXPORT_FUNC (JsiSkPath,rConicTo),JSI_EXPORT_FUNC (JsiSkPath,contains),JSI_EXPORT_FUNC (JsiSkPath,dash),JSI_EXPORT_FUNC (JsiSkPath,equals),JSI_EXPORT_FUNC (JsiSkPath,getFillType),JSI_EXPORT_FUNC (JsiSkPath,setFillType),JSI_EXPORT_FUNC (JsiSkPath,setIsVolatile),JSI_EXPORT_FUNC (JsiSkPath,isVolatile),JSI_EXPORT_FUNC (JsiSkPath,transform),JSI_EXPORT_FUNC (JsiSkPath,stroke),JSI_EXPORT_FUNC (JsiSkPath,trim),JSI_EXPORT_FUNC (JsiSkPath,getPoint),JSI_EXPORT_FUNC (JsiSkPath,toSVGString),JSI_EXPORT_FUNC (JsiSkPath,makeAsWinding),JSI_EXPORT_FUNC (JsiSkPath,isEmpty),JSI_EXPORT_FUNC (JsiSkPath,offset),JSI_EXPORT_FUNC (JsiSkPath,moveTo),JSI_EXPORT_FUNC (JsiSkPath,rMoveTo),JSI_EXPORT_FUNC (JsiSkPath,lineTo),JSI_EXPORT_FUNC (JsiSkPath,rLineTo),JSI_EXPORT_FUNC (JsiSkPath,cubicTo),JSI_EXPORT_FUNC (JsiSkPath,rCubicTo),JSI_EXPORT_FUNC (JsiSkPath,reset),JSI_EXPORT_FUNC (JsiSkPath,rewind),JSI_EXPORT_FUNC (JsiSkPath,quadTo),JSI_EXPORT_FUNC (JsiSkPath,rQuadTo),JSI_EXPORT_FUNC (JsiSkPath,addCircle),JSI_EXPORT_FUNC (JsiSkPath,getLastPt),JSI_EXPORT_FUNC (JsiSkPath,close),JSI_EXPORT_FUNC (JsiSkPath,simplify),JSI_EXPORT_FUNC (JsiSkPath,countPoints),JSI_EXPORT_FUNC (JsiSkPath,copy),JSI_EXPORT_FUNC (JsiSkPath,op),JSI_EXPORT_FUNC (JsiSkPath,isInterpolatable),JSI_EXPORT_FUNC (JsiSkPath,interpolate),JSI_EXPORT_FUNC (JsiSkPath,toCmds),JSI_EXPORT_FUNC (JsiSkPath,dispose))528   JSI_EXPORT_FUNCTIONS(
529       JSI_EXPORT_FUNC(JsiSkPath, addPath), JSI_EXPORT_FUNC(JsiSkPath, addArc),
530       JSI_EXPORT_FUNC(JsiSkPath, addOval), JSI_EXPORT_FUNC(JsiSkPath, addPoly),
531       JSI_EXPORT_FUNC(JsiSkPath, addRect), JSI_EXPORT_FUNC(JsiSkPath, addRRect),
532       JSI_EXPORT_FUNC(JsiSkPath, arcToOval),
533       JSI_EXPORT_FUNC(JsiSkPath, arcToRotated),
534       JSI_EXPORT_FUNC(JsiSkPath, rArcTo),
535       JSI_EXPORT_FUNC(JsiSkPath, arcToTangent),
536       JSI_EXPORT_FUNC(JsiSkPath, computeTightBounds),
537       JSI_EXPORT_FUNC(JsiSkPath, getBounds),
538       JSI_EXPORT_FUNC(JsiSkPath, conicTo), JSI_EXPORT_FUNC(JsiSkPath, rConicTo),
539       JSI_EXPORT_FUNC(JsiSkPath, contains), JSI_EXPORT_FUNC(JsiSkPath, dash),
540       JSI_EXPORT_FUNC(JsiSkPath, equals),
541       JSI_EXPORT_FUNC(JsiSkPath, getFillType),
542       JSI_EXPORT_FUNC(JsiSkPath, setFillType),
543       JSI_EXPORT_FUNC(JsiSkPath, setIsVolatile),
544       JSI_EXPORT_FUNC(JsiSkPath, isVolatile),
545       JSI_EXPORT_FUNC(JsiSkPath, transform), JSI_EXPORT_FUNC(JsiSkPath, stroke),
546       JSI_EXPORT_FUNC(JsiSkPath, trim), JSI_EXPORT_FUNC(JsiSkPath, getPoint),
547       JSI_EXPORT_FUNC(JsiSkPath, toSVGString),
548       JSI_EXPORT_FUNC(JsiSkPath, makeAsWinding),
549       JSI_EXPORT_FUNC(JsiSkPath, isEmpty), JSI_EXPORT_FUNC(JsiSkPath, offset),
550       JSI_EXPORT_FUNC(JsiSkPath, moveTo), JSI_EXPORT_FUNC(JsiSkPath, rMoveTo),
551       JSI_EXPORT_FUNC(JsiSkPath, lineTo), JSI_EXPORT_FUNC(JsiSkPath, rLineTo),
552       JSI_EXPORT_FUNC(JsiSkPath, cubicTo), JSI_EXPORT_FUNC(JsiSkPath, rCubicTo),
553       JSI_EXPORT_FUNC(JsiSkPath, reset), JSI_EXPORT_FUNC(JsiSkPath, rewind),
554       JSI_EXPORT_FUNC(JsiSkPath, quadTo), JSI_EXPORT_FUNC(JsiSkPath, rQuadTo),
555       JSI_EXPORT_FUNC(JsiSkPath, addCircle),
556       JSI_EXPORT_FUNC(JsiSkPath, getLastPt), JSI_EXPORT_FUNC(JsiSkPath, close),
557       JSI_EXPORT_FUNC(JsiSkPath, simplify),
558       JSI_EXPORT_FUNC(JsiSkPath, countPoints), JSI_EXPORT_FUNC(JsiSkPath, copy),
559       JSI_EXPORT_FUNC(JsiSkPath, op),
560       JSI_EXPORT_FUNC(JsiSkPath, isInterpolatable),
561       JSI_EXPORT_FUNC(JsiSkPath, interpolate),
562       JSI_EXPORT_FUNC(JsiSkPath, toCmds), JSI_EXPORT_FUNC(JsiSkPath, dispose))
563 
564   JsiSkPath(std::shared_ptr<RNSkPlatformContext> context, SkPath path)
565       : JsiSkWrappingSharedPtrHostObject<SkPath>(
566             std::move(context), std::make_shared<SkPath>(std::move(path))) {}
567 
toValue(jsi::Runtime & runtime,std::shared_ptr<RNSkPlatformContext> context,const SkPath & path)568   static jsi::Value toValue(jsi::Runtime &runtime,
569                             std::shared_ptr<RNSkPlatformContext> context,
570                             const SkPath &path) {
571     return jsi::Object::createFromHostObject(
572         runtime, std::make_shared<JsiSkPath>(std::move(context), path));
573   }
574 
toValue(jsi::Runtime & runtime,std::shared_ptr<RNSkPlatformContext> context,SkPath && path)575   static jsi::Value toValue(jsi::Runtime &runtime,
576                             std::shared_ptr<RNSkPlatformContext> context,
577                             SkPath &&path) {
578     return jsi::Object::createFromHostObject(
579         runtime,
580         std::make_shared<JsiSkPath>(std::move(context), std::move(path)));
581   }
582 };
583 
584 } // namespace RNSkia
585