diff options
author | Jovansonlee Cesar <ivanceras@gmail.com> | 2022-09-27 08:08:42 +0800 |
---|---|---|
committer | Jovansonlee Cesar <ivanceras@gmail.com> | 2022-09-27 08:08:42 +0800 |
commit | 9be58496da4e0b0dff5aa7700929a5d3732214c1 (patch) | |
tree | 67d3adc43d5f4e9f073d77816c0f2e8201a9785d | |
parent | f0d1514e3497d3cbc3bbd29581b291c911c43326 (diff) |
feat: improve endorse function to use re_endorse
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer.rs | 43 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer/contacts.rs | 10 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer/span.rs | 67 |
3 files changed, 88 insertions, 32 deletions
diff --git a/packages/svgbob/src/buffer/cell_buffer.rs b/packages/svgbob/src/buffer/cell_buffer.rs index f77adf6..ebcc1f3 100644 --- a/packages/svgbob/src/buffer/cell_buffer.rs +++ b/packages/svgbob/src/buffer/cell_buffer.rs @@ -130,14 +130,31 @@ impl CellBuffer { } /// return the fragments that are (close objects, touching grouped fragments) - pub fn get_fragment_spans( - self, - ) -> (Vec<FragmentSpan>, Vec<Vec<FragmentSpan>>) { + /// + /// TODO, this should return (Vec<FragmentSpan>, Vec<Span>), + /// The rejects span must been retried for a circle_spans + /// since there is a change that it was right next to a rect, which + /// prevents if from matching any circle. + /// + /// Once the rects has been matches, then what's left in the span + /// could match to be a circle + pub fn get_fragment_spans(self) -> (Vec<FragmentSpan>, Vec<Span>) { let escaped_text = self.escaped_text_nodes(); - let Endorse { - mut accepted, - rejects, - } = self.endorse_to_fragment_spans(); + + let group_adjacents: Vec<Span> = self.into(); + let (endorsed_fragments, vec_spans): ( + Vec<Vec<FragmentSpan>>, + Vec<Vec<Span>>, + ) = group_adjacents + .into_iter() + .map(|span| span.endorse()) + .map(|endorse| (endorse.accepted, endorse.rejects)) + .unzip(); + + let mut accepted: Vec<FragmentSpan> = + endorsed_fragments.into_iter().flatten().collect(); + + let rejects: Vec<Span> = vec_spans.into_iter().flatten().collect(); accepted.extend(escaped_text); @@ -147,7 +164,6 @@ impl CellBuffer { /// return fragments that are Rect, Circle, pub(crate) fn into_shapes_fragment(self) -> Vec<FragmentSpan> { let endorse = self.endorse_to_fragment_spans(); - println!("endorsed: {:#?}", endorse); endorse .accepted .into_iter() @@ -170,7 +186,16 @@ impl CellBuffer { ) = group_adjacents .into_iter() .map(|span| span.endorse()) - .map(|endorse| (endorse.accepted, endorse.rejects)) + .map(|endorse| { + ( + endorse.accepted, + endorse + .rejects + .into_iter() + .flat_map(|span| <Vec<Contacts>>::from(span)) + .collect::<Vec<Contacts>>(), + ) + }) .unzip(); // partition the vec_groups into groups that is alone and the group diff --git a/packages/svgbob/src/buffer/cell_buffer/contacts.rs b/packages/svgbob/src/buffer/cell_buffer/contacts.rs index d6342e4..02147d7 100644 --- a/packages/svgbob/src/buffer/cell_buffer/contacts.rs +++ b/packages/svgbob/src/buffer/cell_buffer/contacts.rs @@ -80,17 +80,17 @@ impl Contacts { /// to fragments that are touching, to be promoted to a shape. /// These includes: rect, roundedrect, pub(crate) fn endorse_rects( - spans: Vec<Contacts>, + contacts: Vec<Contacts>, ) -> Endorse<FragmentSpan, Contacts> { let mut accepted = vec![]; let mut rejects: Vec<Contacts> = vec![]; - for span in spans { - if let Some(fragment) = span.endorse_rect() { - let span = span.span(); + for contact in contacts { + if let Some(fragment) = contact.endorse_rect() { + let span = contact.span(); let fragment_span = FragmentSpan::new(span, fragment); accepted.push(fragment_span); } else { - rejects.push(span); + rejects.push(contact); } } Endorse { accepted, rejects } diff --git a/packages/svgbob/src/buffer/cell_buffer/span.rs b/packages/svgbob/src/buffer/cell_buffer/span.rs index 42c5f25..fde515e 100644 --- a/packages/svgbob/src/buffer/cell_buffer/span.rs +++ b/packages/svgbob/src/buffer/cell_buffer/span.rs @@ -121,14 +121,55 @@ impl Span { /// convert this span into fragments applying endorsement /// of group into fragments /// - /// returns (fragments, contacts) - - /// The first element of the tuple: `fragments` are the resulting fragment after - /// the endorsement such as rect, rounded rect from lines and arcs. /// - /// The second element of the tuple: `contacts` are fragments that are touching together - /// but can not form a fragment shape. These will be grouped in the svg nodes - /// to keep them go together, when dragged (editing) - pub(crate) fn endorse(self) -> Endorse<FragmentSpan, Contacts> { + /// TODO: return the rejects as Span, instead of Contacts + pub(crate) fn endorse(self) -> Endorse<FragmentSpan, Span> { + // try to endorse as circles or arcs + let (mut accepted, un_endorsed_span): (Vec<FragmentSpan>, Span) = + self.endorse_to_arcs_and_circles(); + + // convert into contacts and try to endorse as rects fragments + let un_endorsed_contacts: Vec<Contacts> = un_endorsed_span.into(); + let rect_endorsed: Endorse<FragmentSpan, Contacts> = + Contacts::endorse_rects(un_endorsed_contacts); + + accepted.extend(rect_endorsed.accepted); + + let re_endorsed = Self::re_endorse(rect_endorsed.rejects); + + let mut endorsed = Endorse { + accepted, + rejects: vec![], + }; + endorsed.extend(re_endorsed); + endorsed + } + + /// re try endorsing the contacts into arc and circles by converting it to span first + fn re_endorse(rect_rejects: Vec<Contacts>) -> Endorse<FragmentSpan, Span> { + // convert back to span + let span_rejects: Vec<Span> = rect_rejects + .into_iter() + .map(|contact| contact.span()) + .collect(); + + let span_rejects: Vec<Span> = Span::merge_recursive(span_rejects); + + // try to endorse as circles or arcs one more time + let (accepted, rejects): (Vec<Vec<FragmentSpan>>, Vec<Span>) = + span_rejects + .into_iter() + .map(|span| span.endorse_to_arcs_and_circles()) + .unzip(); + + Endorse { + accepted: accepted.into_iter().flatten().collect(), + rejects, + } + } + + /// endorse this span into circles, half_circle, quarter_circle only + fn endorse_to_arcs_and_circles(self) -> (Vec<FragmentSpan>, Span) { let mut accepted = vec![]; let (top_left, _) = self.bounds().expect("must have bounds"); let un_endorsed_span: Span = if let Some((circle, un_endorsed_span)) = @@ -157,17 +198,7 @@ impl Span { } else { self }; - - let un_endorsed_contacts: Vec<Contacts> = un_endorsed_span.into(); - let rect_endorse: Endorse<FragmentSpan, Contacts> = - Contacts::endorse_rects(un_endorsed_contacts); - - let mut endorse = Endorse { - accepted, - rejects: vec![], - }; - endorse.extend(rect_endorse); - endorse + (accepted, un_endorsed_span) } /// create a span of the cells that is inside of the start and end bound cells |