Bezier-rs: Fix crash when outlining a small bézier (#1958)

Fix crash when outlining small bézier
This commit is contained in:
James Lindsay 2024-09-05 18:22:24 +01:00 committed by Keavon Chambers
parent 9524835a30
commit bf5019db7b
2 changed files with 42 additions and 8 deletions

View file

@ -368,7 +368,12 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
return self.clone(); return self.clone();
} }
let mut subpaths = self.iter().filter(|bezier| !bezier.is_point()).map(|bezier| bezier.offset(distance)).collect::<Vec<Subpath<PointId>>>(); let mut subpaths = self
.iter()
.filter(|bezier| !bezier.is_point())
.map(|bezier| bezier.offset(distance))
.filter(|subpath| subpath.len() >= 2) // In some cases the reduced and scaled bézier is marked by is_point (so the subpath is empty).
.collect::<Vec<Subpath<PointId>>>();
let mut drop_common_point = vec![true; self.len()]; let mut drop_common_point = vec![true; self.len()];
// Clip or join consecutive Subpaths // Clip or join consecutive Subpaths
@ -636,6 +641,37 @@ mod tests {
assert!(outline.closed()); assert!(outline.closed());
} }
#[test]
/// Even though the bézier here is not marked as a point, the offset and scaled version is.
fn outline_with_point_offset() {
let subpath = Subpath::new(
vec![
ManipulatorGroup {
anchor: DVec2::new(1122.6253015182049, 610.9441551227939),
out_handle: Some(DVec2::new(1122.6253015182049, 610.9445412168651)),
in_handle: None,
id: EmptyId,
},
ManipulatorGroup {
anchor: DVec2::new(1122.6258671405062, 610.9453107605276),
out_handle: None,
in_handle: Some(DVec2::new(1122.6254904904154, 610.9449255479497)),
id: EmptyId,
},
ManipulatorGroup {
anchor: DVec2::new(0., 0.),
out_handle: None,
in_handle: None,
id: EmptyId,
},
],
false,
);
let outline = subpath.outline(4.4, crate::Join::Round, crate::Cap::Round).0;
assert!(outline.manipulator_groups.windows(2).all(|pair| !pair[0].anchor.abs_diff_eq(pair[1].anchor, MAX_ABSOLUTE_DIFFERENCE)));
assert!(outline.closed());
}
#[test] #[test]
fn split_an_open_subpath() { fn split_an_open_subpath() {
let subpath = set_up_open_subpath(); let subpath = set_up_open_subpath();

View file

@ -164,14 +164,12 @@ async fn execute_shader<I: Pod + Send + Sync, O: Pod + Send + Sync>(device: Arc<
// Since contents are got in bytes, this converts these bytes back to u32 // Since contents are got in bytes, this converts these bytes back to u32
let result = bytemuck::cast_slice(&data).to_vec(); let result = bytemuck::cast_slice(&data).to_vec();
// With the current interface, we have to make sure all mapped views are // With the current interface, we have to make sure all mapped views are dropped before we unmap the buffer
// dropped before we unmap the buffer.
drop(data); drop(data);
staging_buffer.unmap(); // Unmaps buffer from memory // Unmaps buffer from memory
// If you are familiar with C++ these 2 lines can be thought of similarly to: staging_buffer.unmap();
// delete myPointer; // If you are familiar with C++ these 2 lines can be thought of similarly to `delete myPointer; myPointer = NULL;`.
// myPointer = NULL; // It effectively frees the memory.
// It effectively frees the memory
// Returns data from buffer // Returns data from buffer
Some(result) Some(result)