Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions lib/ui/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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.
///
Expand Down Expand Up @@ -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.');
Expand Down
18 changes: 8 additions & 10 deletions lib/ui/painting/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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() {
Expand All @@ -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
19 changes: 13 additions & 6 deletions lib/ui/painting/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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_; }

Expand Down
39 changes: 20 additions & 19 deletions lib/ui/painting/path_measure.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
Expand Down
15 changes: 8 additions & 7 deletions lib/ui/painting/path_measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down