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
18 changes: 18 additions & 0 deletions lib/web_ui/lib/src/engine/surface/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,28 @@ class SurfacePath implements ui.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.
SurfacePath.from(SurfacePath source)
: subpaths = _deepCopy(source.subpaths);

SurfacePath._shallowCopy(SurfacePath source)
: subpaths = List<Subpath>.from(source.subpaths);

SurfacePath._clone(this.subpaths, this._fillType);

static List<Subpath> _deepCopy(List<Subpath> source) {
// The last sub path can potentially still be mutated by calling ops.
// Copy all sub paths except the last active one which needs a deep copy.
final List<Subpath> paths = [];
int len = source.length;
if (len != 0) {
--len;
for (int i = 0; i < len; i++) {
paths.add(source[i]);
}
paths.add(source[len].shift(const ui.Offset(0, 0)));
}
return paths;
}

/// Determines how the interior of this path is calculated.
///
/// Defaults to the non-zero winding rule, [PathFillType.nonZero].
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/surface/recording_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ class RecordingCanvas {
}
_paintBounds.grow(pathBounds);
// Clone path so it can be reused for subsequent draw calls.
final ui.Path clone = ui.Path.from(path);
final ui.Path clone = SurfacePath._shallowCopy(path);
clone.fillType = path.fillType;
_commands.add(PaintDrawPath(clone, paint.paintData));
}
Expand Down
14 changes: 14 additions & 0 deletions lib/web_ui/test/path_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -238,4 +238,18 @@ void main() {
distance: 0.1,
from: const Rect.fromLTRB(220.0, 124.1, 382.9, 300.0)));
});

// Regression test for https://github.com/flutter/flutter/issues/46813.
test('Should deep copy path', () {
final SurfacePath path = SurfacePath();
path.moveTo(25, 30);
path.lineTo(100, 200);
expect(path.getBounds(), const Rect.fromLTRB(25, 30, 100, 200));

final SurfacePath path2 = SurfacePath.from(path);
path2.lineTo(250, 300);
expect(path2.getBounds(), const Rect.fromLTRB(25, 30, 250, 300));
// Expect original path to stay the same.
expect(path.getBounds(), const Rect.fromLTRB(25, 30, 100, 200));
});
}