Skip to content

Commit c6c24d2

Browse files
Added glyphsapp style deletion simplification. (#335)
* Removed old edit API and replaced the with_active_layer family of functions with get_active_layer family. * Refactored counter operations. * Removed unnecessary mut due to warning. * Added remove to ContourOp and ContourOpData traits. * Changed selection box behavior. * When a single point is selected we default to simplify. * Removed debug prints. * Added GlyphsApp style point deletion. When you delete a single point on a contour the editor now tries to fit a curve to the previous two curves. This is similar to the deletion behavior in GlyphsApp. * Fixed infinite loop when deleting the start of a contour. Also deleted some debug prints. * Fixed warnings. * Fixed infinite loop Code would enter an infinite loop while deleting start/end of open contour. Removed unnecessary use statements to get rid of warnings. * Rustfmt
1 parent 18dbe3a commit c6c24d2

File tree

16 files changed

+354
-217
lines changed

16 files changed

+354
-217
lines changed

build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn main() {
3737
}
3838
}
3939
} else if #[cfg(all(not(feature = "sdl2-static"), any(target_family = "windows", target_family = "macos"), not(feature = "sdl2-dynamic")))] {
40-
compile_error!("Please pass either the flag --features=sdl2-static (recommended) or --features=sdl2-dynamic (requires you to download SDL2 link library from SDL.org)")
40+
println!("cargo:rustc-cfg=feature=\"sdl2-static\"");
4141
} else if #[cfg(all(target_family = "windows", feature = "sdl2-dynamic"))] {
4242
warning!("It is neither recommended nor supported to compile MFEKglif on Windows w/dynamic SDL2.");
4343
}
Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use glifparser::glif::{DashContour, Glif, MFEKContour, MFEKOutline};
22

3-
use super::ContourOperation;
3+
use super::ContourOperationData;
44
use crate::util::MFEKGlifPointData;
55

6-
impl ContourOperation for DashContour {
6+
impl ContourOperationData for DashContour {
77
fn build(&self, contour: &MFEKContour<MFEKGlifPointData>) -> MFEKOutline<MFEKGlifPointData> {
88
let mut glif = Glif::default();
99
glif.outline = Some(vec![contour.inner.clone()]);
@@ -19,19 +19,15 @@ impl ContourOperation for DashContour {
1919
output
2020
}
2121

22-
fn sub(&self, _contour: &MFEKContour<MFEKGlifPointData>, _begin: usize, _end: usize) -> Self {
23-
self.clone()
24-
}
22+
fn sub(&mut self, _contour: &MFEKContour<MFEKGlifPointData>, _begin: usize, _end: usize) {}
2523

2624
fn append(
27-
&self,
25+
&mut self,
2826
_contour: &MFEKContour<MFEKGlifPointData>,
2927
_append: &MFEKContour<MFEKGlifPointData>,
30-
) -> Self {
31-
self.clone()
28+
) {
3229
}
3330

34-
fn insert(&self, _contour: &MFEKContour<MFEKGlifPointData>, _point_idx: usize) -> Self {
35-
self.clone()
36-
}
31+
fn insert(&mut self, _contour: &MFEKContour<MFEKGlifPointData>, _point_idx: usize) {}
32+
fn remove(&mut self, _contour: &MFEKContour<MFEKGlifPointData>, _point_idx: usize) {}
3733
}

src/contour_operations/mod.rs

Lines changed: 80 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -8,107 +8,111 @@ use glifparser::glif::{ContourOperations, MFEKContour, MFEKOutline};
88

99
use log;
1010

11-
fn unknown_op() -> Option<ContourOperations<MFEKGlifPointData>> {
11+
fn unknown_op() {
1212
log::warn!("Found unknown contour operation attached to contour. File was generated with newer MFEKglif, please upgrade to edit properly.");
13-
None
1413
}
1514

1615
fn unknown_op_outline() -> MFEKOutline<MFEKGlifPointData> {
1716
unknown_op();
1817
MFEKOutline::new()
1918
}
2019

21-
pub trait ContourOperation {
20+
pub trait ContourOperationData {
2221
fn build(&self, contour: &MFEKContour<MFEKGlifPointData>) -> MFEKOutline<MFEKGlifPointData>;
23-
fn sub(&self, contour: &MFEKContour<MFEKGlifPointData>, begin: usize, end: usize) -> Self;
22+
fn sub(&mut self, contour: &MFEKContour<MFEKGlifPointData>, begin: usize, end: usize);
2423
fn append(
25-
&self,
24+
&mut self,
2625
contour: &MFEKContour<MFEKGlifPointData>,
2726
append: &MFEKContour<MFEKGlifPointData>,
28-
) -> Self;
29-
fn insert(&self, contour: &MFEKContour<MFEKGlifPointData>, idx: usize) -> Self;
27+
);
28+
fn remove(&mut self, contour: &MFEKContour<MFEKGlifPointData>, idx: usize);
29+
fn insert(&mut self, contour: &MFEKContour<MFEKGlifPointData>, idx: usize);
3030
}
3131

32-
pub fn sub(
33-
contour: &MFEKContour<MFEKGlifPointData>,
34-
begin: usize,
35-
end: usize,
36-
) -> Option<ContourOperations<MFEKGlifPointData>> {
37-
let op = contour.operation.clone();
38-
op.as_ref()?;
32+
pub trait ContourOperation {
33+
fn build(&self, contour: &MFEKContour<MFEKGlifPointData>) -> MFEKOutline<MFEKGlifPointData>;
34+
fn sub(&mut self, contour: &MFEKContour<MFEKGlifPointData>, begin: usize, end: usize);
35+
fn append(
36+
&mut self,
37+
contour: &MFEKContour<MFEKGlifPointData>,
38+
append: &MFEKContour<MFEKGlifPointData>,
39+
);
40+
fn remove_op(&mut self, contour: &MFEKContour<MFEKGlifPointData>, idx: usize);
41+
fn insert_op(&mut self, contour: &MFEKContour<MFEKGlifPointData>, idx: usize);
42+
}
3943

40-
match op.unwrap() {
41-
ContourOperations::VariableWidthStroke { data } => {
42-
Some(ContourOperations::VariableWidthStroke {
43-
data: data.sub(contour, begin, end),
44-
})
44+
impl ContourOperation for Option<ContourOperations<MFEKGlifPointData>> {
45+
fn sub(&mut self, contour: &MFEKContour<MFEKGlifPointData>, begin: usize, end: usize) {
46+
if let Some(op) = self.as_mut() {
47+
match op {
48+
ContourOperations::VariableWidthStroke { ref mut data } => {
49+
data.sub(contour, begin, end)
50+
}
51+
ContourOperations::PatternAlongPath { ref mut data } => {
52+
data.sub(contour, begin, end)
53+
}
54+
ContourOperations::DashAlongPath { ref mut data } => data.sub(contour, begin, end),
55+
_ => unknown_op(),
56+
}
4557
}
46-
ContourOperations::PatternAlongPath { data } => Some(ContourOperations::PatternAlongPath {
47-
data: data.sub(contour, begin, end),
48-
}),
49-
ContourOperations::DashAlongPath { data } => Some(ContourOperations::DashAlongPath {
50-
data: data.sub(contour, begin, end),
51-
}),
52-
_ => unknown_op(),
5358
}
54-
}
5559

56-
pub fn append(
57-
contour: &MFEKContour<MFEKGlifPointData>,
58-
append: &MFEKContour<MFEKGlifPointData>,
59-
) -> Option<ContourOperations<MFEKGlifPointData>> {
60-
let op = contour.operation.clone();
61-
op.as_ref()?;
62-
63-
match op.unwrap() {
64-
ContourOperations::VariableWidthStroke { data } => {
65-
Some(ContourOperations::VariableWidthStroke {
66-
data: data.append(contour, append),
67-
})
60+
fn append(
61+
&mut self,
62+
contour: &MFEKContour<MFEKGlifPointData>,
63+
append: &MFEKContour<MFEKGlifPointData>,
64+
) {
65+
if let Some(op) = self.as_mut() {
66+
match op {
67+
ContourOperations::VariableWidthStroke { ref mut data } => {
68+
data.append(contour, append)
69+
}
70+
ContourOperations::PatternAlongPath { ref mut data } => {
71+
data.append(contour, append)
72+
}
73+
ContourOperations::DashAlongPath { ref mut data } => data.append(contour, append),
74+
_ => unknown_op(),
75+
}
6876
}
69-
ContourOperations::PatternAlongPath { data } => Some(ContourOperations::PatternAlongPath {
70-
data: data.append(contour, append),
71-
}),
72-
ContourOperations::DashAlongPath { data } => Some(ContourOperations::DashAlongPath {
73-
data: data.append(contour, append),
74-
}),
75-
_ => unknown_op(),
7677
}
77-
}
7878

79-
pub fn build(contour: &MFEKContour<MFEKGlifPointData>) -> MFEKOutline<MFEKGlifPointData> {
80-
let op = contour.operation.clone();
81-
if op.is_none() {
82-
return vec![contour.clone()];
83-
}
79+
fn build(&self, contour: &MFEKContour<MFEKGlifPointData>) -> MFEKOutline<MFEKGlifPointData> {
80+
let op = contour.operation.clone();
81+
if op.is_none() {
82+
return vec![contour.clone()];
83+
}
8484

85-
match op.unwrap() {
86-
ContourOperations::VariableWidthStroke { data } => data.build(contour),
87-
ContourOperations::PatternAlongPath { data } => data.build(contour),
88-
ContourOperations::DashAlongPath { data } => data.build(contour),
89-
_ => unknown_op_outline(),
85+
match op.unwrap() {
86+
ContourOperations::VariableWidthStroke { data } => data.build(contour),
87+
ContourOperations::PatternAlongPath { data } => data.build(contour),
88+
ContourOperations::DashAlongPath { data } => data.build(contour),
89+
_ => unknown_op_outline(),
90+
}
9091
}
91-
}
9292

93-
pub fn insert(
94-
contour: &MFEKContour<MFEKGlifPointData>,
95-
idx: usize,
96-
) -> Option<ContourOperations<MFEKGlifPointData>> {
97-
let op = contour.operation.clone();
98-
op.as_ref()?;
93+
fn insert_op(&mut self, contour: &MFEKContour<MFEKGlifPointData>, idx: usize) {
94+
if let Some(op) = self.as_mut() {
95+
match op {
96+
ContourOperations::VariableWidthStroke { ref mut data } => {
97+
data.insert(contour, idx)
98+
}
99+
ContourOperations::PatternAlongPath { ref mut data } => data.insert(contour, idx),
100+
ContourOperations::DashAlongPath { ref mut data } => data.insert(contour, idx),
101+
_ => unknown_op(),
102+
}
103+
}
104+
}
99105

100-
match op.unwrap() {
101-
ContourOperations::VariableWidthStroke { data } => {
102-
Some(ContourOperations::VariableWidthStroke {
103-
data: data.insert(contour, idx),
104-
})
106+
fn remove_op(&mut self, contour: &MFEKContour<MFEKGlifPointData>, idx: usize) {
107+
if let Some(op) = self.as_mut() {
108+
match op {
109+
ContourOperations::VariableWidthStroke { ref mut data } => {
110+
data.remove(contour, idx)
111+
}
112+
ContourOperations::PatternAlongPath { ref mut data } => data.remove(contour, idx),
113+
ContourOperations::DashAlongPath { ref mut data } => data.remove(contour, idx),
114+
_ => unknown_op(),
115+
}
105116
}
106-
ContourOperations::PatternAlongPath { data } => Some(ContourOperations::PatternAlongPath {
107-
data: data.insert(contour, idx),
108-
}),
109-
ContourOperations::DashAlongPath { data } => Some(ContourOperations::DashAlongPath {
110-
data: data.insert(contour, idx),
111-
}),
112-
_ => unknown_op(),
113117
}
114118
}
Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use glifparser::glif::{MFEKContour, MFEKOutline, PAPContour};
22
use MFEKmath::{pattern_along_path_mfek, Piecewise};
33

4-
use super::ContourOperation;
4+
use super::ContourOperationData;
55
use crate::util::MFEKGlifPointData;
66

7-
impl ContourOperation for PAPContour<MFEKGlifPointData> {
7+
impl ContourOperationData for PAPContour<MFEKGlifPointData> {
88
fn build(&self, contour: &MFEKContour<MFEKGlifPointData>) -> MFEKOutline<MFEKGlifPointData> {
99
let contour_pw = Piecewise::from(&contour.inner);
1010

@@ -18,19 +18,15 @@ impl ContourOperation for PAPContour<MFEKGlifPointData> {
1818
output
1919
}
2020

21-
fn sub(&self, _contour: &MFEKContour<MFEKGlifPointData>, _begin: usize, _end: usize) -> Self {
22-
self.clone()
23-
}
21+
fn sub(&mut self, _contour: &MFEKContour<MFEKGlifPointData>, _begin: usize, _end: usize) {}
2422

2523
fn append(
26-
&self,
24+
&mut self,
2725
_contour: &MFEKContour<MFEKGlifPointData>,
2826
_append: &MFEKContour<MFEKGlifPointData>,
29-
) -> Self {
30-
self.clone()
27+
) {
3128
}
3229

33-
fn insert(&self, _contour: &MFEKContour<MFEKGlifPointData>, _point_idx: usize) -> Self {
34-
self.clone()
35-
}
30+
fn insert(&mut self, _contour: &MFEKContour<MFEKGlifPointData>, _point_idx: usize) {}
31+
fn remove(&mut self, _contour: &MFEKContour<MFEKGlifPointData>, _point_idx: usize) {}
3632
}

src/contour_operations/variablewidthstroke.rs

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use glifparser::{
44
};
55
use MFEKmath::{variable_width_stroke, Piecewise, VWSSettings};
66

7-
use super::ContourOperation;
7+
use super::ContourOperationData;
88
use crate::util::MFEKGlifPointData;
99

10-
impl ContourOperation for VWSContour {
10+
impl ContourOperationData for VWSContour {
1111
fn build(&self, contour: &MFEKContour<MFEKGlifPointData>) -> MFEKOutline<MFEKGlifPointData> {
1212
let contour_pw = Piecewise::from(&contour.inner);
1313

@@ -26,24 +26,18 @@ impl ContourOperation for VWSContour {
2626
output
2727
}
2828

29-
fn sub(&self, _contour: &MFEKContour<MFEKGlifPointData>, begin: usize, end: usize) -> Self {
29+
fn sub(&mut self, _contour: &MFEKContour<MFEKGlifPointData>, begin: usize, end: usize) {
3030
let temp_handles = self.handles.split_at(begin);
3131
let (final_handles, _) = temp_handles.1.split_at(end + 1 - begin);
32-
VWSContour {
33-
handles: final_handles.into(),
34-
join_type: self.join_type,
35-
cap_start_type: self.cap_start_type,
36-
cap_end_type: self.cap_end_type,
37-
remove_internal: self.remove_internal,
38-
remove_external: self.remove_external,
39-
}
32+
33+
self.handles = final_handles.into();
4034
}
4135

4236
fn append(
43-
&self,
37+
&mut self,
4438
_contour: &MFEKContour<MFEKGlifPointData>,
4539
append: &MFEKContour<MFEKGlifPointData>,
46-
) -> Self {
40+
) {
4741
let mut temp_handles = self.handles.clone();
4842

4943
match append.operation.clone() {
@@ -74,35 +68,22 @@ impl ContourOperation for VWSContour {
7468
}
7569
}
7670

77-
VWSContour {
78-
handles: temp_handles,
79-
join_type: self.join_type,
80-
cap_start_type: self.cap_start_type,
81-
cap_end_type: self.cap_end_type,
82-
remove_internal: self.remove_internal,
83-
remove_external: self.remove_external,
84-
}
71+
self.handles = temp_handles;
8572
}
8673

87-
fn insert(&self, _contour: &MFEKContour<MFEKGlifPointData>, point_idx: usize) -> Self {
88-
let mut temp_handles = self.handles.clone();
89-
temp_handles.insert(
74+
fn insert(&mut self, _contour: &MFEKContour<MFEKGlifPointData>, point_idx: usize) {
75+
self.handles.insert(
9076
point_idx,
9177
VWSHandle {
92-
left_offset: temp_handles[point_idx].left_offset,
93-
right_offset: temp_handles[point_idx].right_offset,
94-
tangent_offset: temp_handles[point_idx].tangent_offset,
95-
interpolation: temp_handles[point_idx].interpolation,
78+
left_offset: self.handles[point_idx].left_offset,
79+
right_offset: self.handles[point_idx].right_offset,
80+
tangent_offset: self.handles[point_idx].tangent_offset,
81+
interpolation: self.handles[point_idx].interpolation,
9682
},
9783
);
84+
}
9885

99-
VWSContour {
100-
handles: temp_handles,
101-
join_type: self.join_type,
102-
cap_start_type: self.cap_start_type,
103-
cap_end_type: self.cap_end_type,
104-
remove_internal: self.remove_internal,
105-
remove_external: self.remove_external,
106-
}
86+
fn remove(&mut self, _contour: &MFEKContour<MFEKGlifPointData>, point_idx: usize) {
87+
self.handles.remove(point_idx);
10788
}
10889
}

0 commit comments

Comments
 (0)