diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index 2d3b230d2ecb0..8497cb065834c 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -1893,20 +1893,20 @@ class Path extends NativeFieldWrapperClass2 { Path() { _constructor(); } void _constructor() native 'Path_constructor'; - // Workaround for tonic, which expects classes with native fields to have a - // private constructor. - // TODO(dnfield): rework this to use ClaimNativeField - https://github.com/flutter/flutter/issues/50997 - @pragma('vm:entry-point') - Path._() { _constructor(); } + /// Avoids creating a new native backing for the path for methods that will + /// create it later, such as [Path.from], [shift] and [transform]. + Path._(); /// Creates a copy of another [Path]. /// /// This copy is fast and does not require additional memory unless either /// the `source` path or the path returned by this constructor are modified. factory Path.from(Path source) { - return source._clone(); + final Path clonedPath = Path._(); + source._clone(clonedPath); + return clonedPath; } - Path _clone() native 'Path_clone'; + void _clone(Path outPath) native 'Path_clone'; /// Determines how the interior of this path is calculated. /// @@ -2169,17 +2169,21 @@ class Path extends NativeFieldWrapperClass2 { /// sub-path translated by the given offset. Path shift(Offset offset) { assert(_offsetIsValid(offset)); - return _shift(offset.dx, offset.dy); + final Path path = Path._(); + _shift(path, offset.dx, offset.dy); + return path; } - Path _shift(double dx, double dy) native 'Path_shift'; + void _shift(Path outPath, double dx, double dy) native 'Path_shift'; /// Returns a copy of the path with all the segments of every /// sub-path transformed by the given matrix. Path transform(Float64List matrix4) { assert(_matrix4IsValid(matrix4)); - return _transform(matrix4); + final Path path = Path._(); + _transform(path, matrix4); + return path; } - Path _transform(Float64List matrix4) native 'Path_transform'; + void _transform(Path outPath, Float64List matrix4) native 'Path_transform'; /// Computes the bounding rectangle for this path. /// @@ -2455,9 +2459,11 @@ class _PathMeasure extends NativeFieldWrapperClass2 { Path extractPath(int contourIndex, double start, double end, {bool startWithMoveTo = true}) { assert(contourIndex <= currentContourIndex, 'Iterator must be advanced before index $contourIndex can be used.'); - return _extractPath(contourIndex, start, end, startWithMoveTo: startWithMoveTo); + final Path path = Path._(); + _extractPath(path, contourIndex, start, end, startWithMoveTo: startWithMoveTo); + return path; } - Path _extractPath(int contourIndex, double start, double end, {bool startWithMoveTo = true}) native 'PathMeasure_getSegment'; + void _extractPath(Path outPath, int contourIndex, double start, double end, {bool startWithMoveTo = true}) native 'PathMeasure_getSegment'; bool isClosed(int contourIndex) { assert(contourIndex <= currentContourIndex, 'Iterator must be advanced before index $contourIndex can be used.'); diff --git a/lib/ui/painting/path.cc b/lib/ui/painting/path.cc index e9f74255b5b9a..0c053c558d332 100644 --- a/lib/ui/painting/path.cc +++ b/lib/ui/painting/path.cc @@ -20,7 +20,7 @@ namespace flutter { typedef CanvasPath Path; static void Path_constructor(Dart_NativeArguments args) { - DartCallConstructor(&CanvasPath::Create, args); + DartCallConstructor(&CanvasPath::CreateNew, args); } IMPLEMENT_WRAPPERTYPEINFO(ui, Path); @@ -262,17 +262,16 @@ bool CanvasPath::contains(double x, double y) { return path_.contains(x, y); } -fml::RefPtr CanvasPath::shift(double dx, double dy) { - fml::RefPtr path = CanvasPath::Create(); +void CanvasPath::shift(Dart_Handle path_handle, double dx, double dy) { + fml::RefPtr path = CanvasPath::Create(path_handle); path_.offset(dx, dy, &path->path_); - return path; } -fml::RefPtr CanvasPath::transform(tonic::Float64List& matrix4) { - fml::RefPtr path = CanvasPath::Create(); +void CanvasPath::transform(Dart_Handle path_handle, + tonic::Float64List& matrix4) { + fml::RefPtr path = CanvasPath::Create(path_handle); path_.transform(ToSkMatrix(matrix4), &path->path_); matrix4.Release(); - return path; } tonic::Float32List CanvasPath::getBounds() { @@ -289,12 +288,11 @@ bool CanvasPath::op(CanvasPath* path1, CanvasPath* path2, int operation) { return Op(path1->path(), path2->path(), (SkPathOp)operation, &path_); } -fml::RefPtr CanvasPath::clone() { - fml::RefPtr path = CanvasPath::Create(); +void CanvasPath::clone(Dart_Handle path_handle) { + fml::RefPtr path = CanvasPath::Create(path_handle); // per Skia docs, this will create a fast copy // data is shared until the source path or dest path are mutated path->path_ = path_; - return path; } } // namespace flutter diff --git a/lib/ui/painting/path.h b/lib/ui/painting/path.h index c7be3c83b9f87..7deb50e4e7d7c 100644 --- a/lib/ui/painting/path.h +++ b/lib/ui/painting/path.h @@ -23,12 +23,19 @@ class CanvasPath : public RefCountedDartWrappable { public: ~CanvasPath() override; - static fml::RefPtr Create() { + static fml::RefPtr CreateNew(Dart_Handle path_handle) { return fml::MakeRefCounted(); } - static fml::RefPtr CreateFrom(const SkPath& src) { - fml::RefPtr path = CanvasPath::Create(); + static fml::RefPtr Create(Dart_Handle path_handle) { + auto path = fml::MakeRefCounted(); + path->AssociateWithDartWrapper(path_handle); + return path; + } + + static fml::RefPtr CreateFrom(Dart_Handle path_handle, + const SkPath& src) { + fml::RefPtr path = CanvasPath::Create(path_handle); path->path_ = src; return path; } @@ -95,11 +102,11 @@ class CanvasPath : public RefCountedDartWrappable { void close(); void reset(); bool contains(double x, double y); - fml::RefPtr shift(double dx, double dy); - fml::RefPtr transform(tonic::Float64List& matrix4); + void shift(Dart_Handle path_handle, double dx, double dy); + void transform(Dart_Handle path_handle, tonic::Float64List& matrix4); tonic::Float32List getBounds(); bool op(CanvasPath* path1, CanvasPath* path2, int operation); - fml::RefPtr clone(); + void clone(Dart_Handle path_handle); const SkPath& path() const { return path_; } diff --git a/lib/ui/painting/path_measure.cc b/lib/ui/painting/path_measure.cc index d195485d83652..2bc35cab4479c 100644 --- a/lib/ui/painting/path_measure.cc +++ b/lib/ui/painting/path_measure.cc @@ -65,26 +65,26 @@ void CanvasPathMeasure::setPath(const CanvasPath* path, bool isClosed) { path_measure_->reset(skPath, isClosed); } -float CanvasPathMeasure::getLength(int contourIndex) { +float CanvasPathMeasure::getLength(int contour_index) { if (static_cast>::size_type>( - contourIndex) < measures_.size()) { - return measures_[contourIndex]->length(); + contour_index) < measures_.size()) { + return measures_[contour_index]->length(); } return -1; } -tonic::Float32List CanvasPathMeasure::getPosTan(int contourIndex, +tonic::Float32List CanvasPathMeasure::getPosTan(int contour_index, float distance) { tonic::Float32List posTan(Dart_NewTypedData(Dart_TypedData_kFloat32, 5)); posTan[0] = 0; // dart code will check for this for failure if (static_cast>::size_type>( - contourIndex) >= measures_.size()) { + contour_index) >= measures_.size()) { return posTan; } SkPoint pos; SkVector tan; - bool success = measures_[contourIndex]->getPosTan(distance, &pos, &tan); + bool success = measures_[contour_index]->getPosTan(distance, &pos, &tan); if (success) { posTan[0] = 1; // dart code will check for this for success @@ -97,28 +97,29 @@ tonic::Float32List CanvasPathMeasure::getPosTan(int contourIndex, return posTan; } -fml::RefPtr CanvasPathMeasure::getSegment(int contourIndex, - float startD, - float stopD, - bool startWithMoveTo) { +void CanvasPathMeasure::getSegment(Dart_Handle path_handle, + int contour_index, + float start_d, + float stop_d, + bool start_with_move_to) { if (static_cast>::size_type>( - contourIndex) >= measures_.size()) { - return CanvasPath::Create(); + contour_index) >= measures_.size()) { + CanvasPath::Create(path_handle); } SkPath dst; - bool success = - measures_[contourIndex]->getSegment(startD, stopD, &dst, startWithMoveTo); + bool success = measures_[contour_index]->getSegment(start_d, stop_d, &dst, + start_with_move_to); if (!success) { - return CanvasPath::Create(); + CanvasPath::Create(path_handle); } else { - return CanvasPath::CreateFrom(dst); + CanvasPath::CreateFrom(path_handle, dst); } } -bool CanvasPathMeasure::isClosed(int contourIndex) { +bool CanvasPathMeasure::isClosed(int contour_index) { if (static_cast>::size_type>( - contourIndex) < measures_.size()) { - return measures_[contourIndex]->isClosed(); + contour_index) < measures_.size()) { + return measures_[contour_index]->isClosed(); } return false; } diff --git a/lib/ui/painting/path_measure.h b/lib/ui/painting/path_measure.h index f73a1b941002d..85a967919ed69 100644 --- a/lib/ui/painting/path_measure.h +++ b/lib/ui/painting/path_measure.h @@ -32,13 +32,14 @@ class CanvasPathMeasure : public RefCountedDartWrappable { bool forceClosed); void setPath(const CanvasPath* path, bool isClosed); - float getLength(int contourIndex); - tonic::Float32List getPosTan(int contourIndex, float distance); - fml::RefPtr getSegment(int contourIndex, - float startD, - float stopD, - bool startWithMoveTo); - bool isClosed(int contourIndex); + float getLength(int contour_index); + tonic::Float32List getPosTan(int contour_index, float distance); + void getSegment(Dart_Handle path_handle, + int contour_index, + float start_d, + float stop_d, + bool start_with_move_to); + bool isClosed(int contour_index); bool nextContour(); static void RegisterNatives(tonic::DartLibraryNatives* natives);