mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Fix invalid segment crash when disolving point loop (#1959)
* Fix invalid segment crash * Further improve robustness
This commit is contained in:
@@ -198,16 +198,47 @@ impl SegmentDomain {
|
||||
self.stroke.clear();
|
||||
}
|
||||
|
||||
pub fn retain(&mut self, f: impl Fn(&SegmentId) -> bool) {
|
||||
let mut keep = self.ids.iter().map(&f);
|
||||
pub fn retain(&mut self, f: impl Fn(&SegmentId) -> bool, points_length: usize) {
|
||||
let additional_delete_ids = self
|
||||
.ids
|
||||
.iter()
|
||||
.zip(&self.start_point)
|
||||
.zip(&self.end_point)
|
||||
.filter(|((_, start), end)| **start >= points_length || **end >= points_length)
|
||||
.map(|x| *x.0 .0)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let can_delete = || {
|
||||
let f = &f;
|
||||
let mut delete_iter = additional_delete_ids.iter().peekable();
|
||||
move |id| {
|
||||
if delete_iter.peek() == Some(&id) {
|
||||
delete_iter.next();
|
||||
false
|
||||
} else {
|
||||
f(id)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut keep = self.ids.iter().map(can_delete());
|
||||
self.start_point.retain(|_| keep.next().unwrap_or_default());
|
||||
let mut keep = self.ids.iter().map(&f);
|
||||
let mut keep = self.ids.iter().map(can_delete());
|
||||
self.end_point.retain(|_| keep.next().unwrap_or_default());
|
||||
let mut keep = self.ids.iter().map(&f);
|
||||
let mut keep = self.ids.iter().map(can_delete());
|
||||
self.handles.retain(|_| keep.next().unwrap_or_default());
|
||||
let mut keep = self.ids.iter().map(&f);
|
||||
let mut keep = self.ids.iter().map(can_delete());
|
||||
self.stroke.retain(|_| keep.next().unwrap_or_default());
|
||||
self.ids.retain(f);
|
||||
|
||||
let mut delete_iter = additional_delete_ids.iter().peekable();
|
||||
self.ids.retain(move |id| {
|
||||
if delete_iter.peek() == Some(&id) {
|
||||
delete_iter.next();
|
||||
false
|
||||
} else {
|
||||
f(id)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn ids(&self) -> &[SegmentId] {
|
||||
|
||||
@@ -101,7 +101,7 @@ pub struct SegmentModification {
|
||||
impl SegmentModification {
|
||||
/// Apply this modification to the specified [`SegmentDomain`].
|
||||
pub fn apply(&self, segment_domain: &mut SegmentDomain, point_domain: &PointDomain) {
|
||||
segment_domain.retain(|id| !self.remove.contains(id));
|
||||
segment_domain.retain(|id| !self.remove.contains(id), point_domain.ids().len());
|
||||
|
||||
for (id, point) in segment_domain.start_point_mut() {
|
||||
let Some(&new) = self.start_point.get(&id) else { continue };
|
||||
@@ -206,8 +206,16 @@ impl SegmentModification {
|
||||
segment_domain.push(add_id, start_index, end_index, handles, stroke);
|
||||
}
|
||||
|
||||
assert!(segment_domain.start_point().iter().all(|&index| index < point_domain.ids().len()), "index should be in range");
|
||||
assert!(segment_domain.end_point().iter().all(|&index| index < point_domain.ids().len()), "index should be in range");
|
||||
assert!(
|
||||
segment_domain.start_point().iter().all(|&index| index < point_domain.ids().len()),
|
||||
"index should be in range {:#?}",
|
||||
segment_domain
|
||||
);
|
||||
assert!(
|
||||
segment_domain.end_point().iter().all(|&index| index < point_domain.ids().len()),
|
||||
"index should be in range {:#?}",
|
||||
segment_domain
|
||||
);
|
||||
}
|
||||
|
||||
/// Create a new modification that will convert an empty [`VectorData`] into the target [`VectorData`].
|
||||
|
||||
Reference in New Issue
Block a user