summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJovansonlee Cesar <ivanceras@gmail.com>2022-09-27 08:08:42 +0800
committerJovansonlee Cesar <ivanceras@gmail.com>2022-09-27 08:08:42 +0800
commit9be58496da4e0b0dff5aa7700929a5d3732214c1 (patch)
tree67d3adc43d5f4e9f073d77816c0f2e8201a9785d
parentf0d1514e3497d3cbc3bbd29581b291c911c43326 (diff)
feat: improve endorse function to use re_endorse
-rw-r--r--packages/svgbob/src/buffer/cell_buffer.rs43
-rw-r--r--packages/svgbob/src/buffer/cell_buffer/contacts.rs10
-rw-r--r--packages/svgbob/src/buffer/cell_buffer/span.rs67
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