Migrate Path to AssociateWithDartWrapper (flutter/engine#16753)

This commit is contained in:
Dan Field 2020-02-22 12:59:35 -08:00 committed by GitHub
parent 1e37bb489a
commit 9bbbd5078d
5 changed files with 68 additions and 55 deletions

View File

@ -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.');

View File

@ -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> CanvasPath::shift(double dx, double dy) {
fml::RefPtr<CanvasPath> path = CanvasPath::Create();
void CanvasPath::shift(Dart_Handle path_handle, double dx, double dy) {
fml::RefPtr<CanvasPath> path = CanvasPath::Create(path_handle);
path_.offset(dx, dy, &path->path_);
return path;
}
fml::RefPtr<CanvasPath> CanvasPath::transform(tonic::Float64List& matrix4) {
fml::RefPtr<CanvasPath> path = CanvasPath::Create();
void CanvasPath::transform(Dart_Handle path_handle,
tonic::Float64List& matrix4) {
fml::RefPtr<CanvasPath> 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> CanvasPath::clone() {
fml::RefPtr<CanvasPath> path = CanvasPath::Create();
void CanvasPath::clone(Dart_Handle path_handle) {
fml::RefPtr<CanvasPath> 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

View File

@ -23,12 +23,19 @@ class CanvasPath : public RefCountedDartWrappable<CanvasPath> {
public:
~CanvasPath() override;
static fml::RefPtr<CanvasPath> Create() {
static fml::RefPtr<CanvasPath> CreateNew(Dart_Handle path_handle) {
return fml::MakeRefCounted<CanvasPath>();
}
static fml::RefPtr<CanvasPath> CreateFrom(const SkPath& src) {
fml::RefPtr<CanvasPath> path = CanvasPath::Create();
static fml::RefPtr<CanvasPath> Create(Dart_Handle path_handle) {
auto path = fml::MakeRefCounted<CanvasPath>();
path->AssociateWithDartWrapper(path_handle);
return path;
}
static fml::RefPtr<CanvasPath> CreateFrom(Dart_Handle path_handle,
const SkPath& src) {
fml::RefPtr<CanvasPath> path = CanvasPath::Create(path_handle);
path->path_ = src;
return path;
}
@ -95,11 +102,11 @@ class CanvasPath : public RefCountedDartWrappable<CanvasPath> {
void close();
void reset();
bool contains(double x, double y);
fml::RefPtr<CanvasPath> shift(double dx, double dy);
fml::RefPtr<CanvasPath> 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<CanvasPath> clone();
void clone(Dart_Handle path_handle);
const SkPath& path() const { return path_; }

View File

@ -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<std::vector<sk_sp<SkContourMeasure>>::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<std::vector<sk_sp<SkContourMeasure>>::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<CanvasPath> 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<std::vector<sk_sp<SkContourMeasure>>::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<std::vector<sk_sp<SkContourMeasure>>::size_type>(
contourIndex) < measures_.size()) {
return measures_[contourIndex]->isClosed();
contour_index) < measures_.size()) {
return measures_[contour_index]->isClosed();
}
return false;
}

View File

@ -32,13 +32,14 @@ class CanvasPathMeasure : public RefCountedDartWrappable<CanvasPathMeasure> {
bool forceClosed);
void setPath(const CanvasPath* path, bool isClosed);
float getLength(int contourIndex);
tonic::Float32List getPosTan(int contourIndex, float distance);
fml::RefPtr<CanvasPath> 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);