diff options
author | Jovansonlee Cesar <ivanceras@gmail.com> | 2022-09-20 14:40:15 +0800 |
---|---|---|
committer | Jovansonlee Cesar <ivanceras@gmail.com> | 2022-09-20 14:40:15 +0800 |
commit | 8ffc9d4e784b3d83dfd3a1f1e59eb03a79b97927 (patch) | |
tree | 7f9c8db427e03b0fde219bc78ce46ade1849793c | |
parent | f05feb09dd34eb064afbf3321e79bac9802dd755 (diff) |
feat: use FragmentSpan for most fragments
-rw-r--r-- | packages/svgbob/src/buffer.rs | 4 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer.rs | 54 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer/contacts.rs | 14 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer/span.rs | 12 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/fragment_buffer.rs | 6 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/fragment_buffer/fragment_span.rs | 15 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/fragment_buffer/fragment_tree.rs | 17 | ||||
-rw-r--r-- | packages/svgbob/src/lib.rs | 2 |
8 files changed, 84 insertions, 40 deletions
diff --git a/packages/svgbob/src/buffer.rs b/packages/svgbob/src/buffer.rs index 30921f1..9238fb6 100644 --- a/packages/svgbob/src/buffer.rs +++ b/packages/svgbob/src/buffer.rs @@ -1,6 +1,8 @@ pub use cell_buffer::{Cell, CellBuffer, CellGrid, Contacts, Span}; pub use fragment_buffer::Direction; -pub use fragment_buffer::{fragment, fragment::Fragment, FragmentBuffer}; +pub use fragment_buffer::{ + fragment, fragment::Fragment, FragmentBuffer, FragmentSpan, +}; pub use property_buffer::{Property, PropertyBuffer, Signal}; pub use string_buffer::StringBuffer; diff --git a/packages/svgbob/src/buffer/cell_buffer.rs b/packages/svgbob/src/buffer/cell_buffer.rs index 0e4192b..03e1af8 100644 --- a/packages/svgbob/src/buffer/cell_buffer.rs +++ b/packages/svgbob/src/buffer/cell_buffer.rs @@ -1,3 +1,4 @@ +use crate::buffer::fragment_buffer::FragmentSpan; use crate::fragment::CellText; use crate::Settings; use crate::{ @@ -189,16 +190,19 @@ impl CellBuffer { } /// return fragments that are Rect, Circle, - pub fn get_shapes_fragment(&self, settings: &Settings) -> Vec<Fragment> { + pub fn get_shapes_fragment( + &self, + settings: &Settings, + ) -> Vec<FragmentSpan> { + log::warn!("Getting shapes fragment.."); let (single_member, _, endorsed_fragments) = self.group_single_members_from_other_fragments(settings); + log::info!("single_members: {:#?}", single_member); endorsed_fragments .into_iter() - .chain( - single_member - .into_iter() - .filter(|frag| frag.is_rect() || frag.is_circle()), - ) + .chain(single_member.into_iter().filter(|frag| { + frag.fragment.is_rect() || frag.fragment.is_circle() + })) .collect() } @@ -206,13 +210,13 @@ impl CellBuffer { fn group_single_members_from_other_fragments( &self, settings: &Settings, - ) -> (Vec<Fragment>, Vec<Vec<Fragment>>, Vec<Fragment>) { + ) -> (Vec<FragmentSpan>, Vec<Vec<FragmentSpan>>, Vec<FragmentSpan>) { // endorsed_fragments are the fragment result of successful endorsement // // vec_groups are not endorsed, but are still touching, these will be grouped together in // the svg node let (endorsed_fragments, vec_contacts): ( - Vec<Vec<Fragment>>, + Vec<Vec<FragmentSpan>>, Vec<Vec<Contacts>>, ) = self .group_adjacents() @@ -220,6 +224,8 @@ impl CellBuffer { .map(|span| span.endorse(settings)) .unzip(); + log::info!("endorsed fragments: {:#?}", endorsed_fragments); + // partition the vec_groups into groups that is alone and the group // that is contacting their parts let (single_member, vec_groups): (Vec<Contacts>, Vec<Contacts>) = @@ -228,29 +234,29 @@ impl CellBuffer { .flatten() .partition(move |contacts| contacts.0.len() == 1); - let single_member_fragments: Vec<Fragment> = single_member + let single_member_fragments: Vec<FragmentSpan> = single_member .into_iter() .flat_map(|contact| { contact - .fragments() + .as_ref() .into_iter() .map(|frag| frag.clone()) - .collect::<Vec<Fragment>>() + .collect::<Vec<FragmentSpan>>() }) .collect(); - let vec_groups: Vec<Vec<Fragment>> = vec_groups + let vec_groups: Vec<Vec<FragmentSpan>> = vec_groups .into_iter() .map(|contact| { contact - .fragments() + .as_ref() .into_iter() .map(|frag| frag.clone()) - .collect::<Vec<Fragment>>() + .collect::<Vec<FragmentSpan>>() }) .collect(); - let endorsed_fragments: Vec<Fragment> = + let endorsed_fragments: Vec<FragmentSpan> = endorsed_fragments.into_iter().flatten().collect(); (single_member_fragments, vec_groups, endorsed_fragments) @@ -261,7 +267,7 @@ impl CellBuffer { fn group_nodes_and_fragments<MSG>( &self, settings: &Settings, - ) -> (Vec<Node<MSG>>, Vec<Fragment>) { + ) -> (Vec<Node<MSG>>, Vec<FragmentSpan>) { let (single_member_fragments, vec_group_fragments, vec_fragments) = self.group_single_members_from_other_fragments(settings); @@ -273,7 +279,7 @@ impl CellBuffer { .iter() .map(move |gfrag| { let scaled = gfrag.scale(settings.scale); - let node: Node<MSG> = scaled.into(); + let node: Node<MSG> = scaled.fragment.into(); node }) .collect::<Vec<Node<MSG>>>(); @@ -281,7 +287,7 @@ impl CellBuffer { }) .collect(); - let mut fragments: Vec<Fragment> = vec_fragments; + let mut fragments: Vec<FragmentSpan> = vec_fragments; fragments.extend(single_member_fragments); fragments.extend(self.escaped_text_nodes()); @@ -289,11 +295,15 @@ impl CellBuffer { (group_nodes, fragments) } - fn escaped_text_nodes(&self) -> Vec<Fragment> { + fn escaped_text_nodes(&self) -> Vec<FragmentSpan> { let mut fragments = vec![]; for (cell, text) in &self.escaped_text { let cell_text = CellText::new(*cell, text.to_string()); - fragments.push(cell_text.into()); + let cells: Vec<(Cell, char)> = + text.chars().into_iter().map(|ch| (*cell, ch)).collect(); + let span = Span::from(cells); + let frag_span_text = FragmentSpan::new(span, cell_text.into()); + fragments.push(frag_span_text); } fragments } @@ -405,13 +415,13 @@ impl CellBuffer { /// convert the fragments into svg nodes using the supplied settings, with size for the /// dimension pub fn fragments_to_node<MSG>( - fragments: Vec<Fragment>, + fragments: Vec<FragmentSpan>, legend_css: String, settings: &Settings, w: f32, h: f32, ) -> Node<MSG> { - let fragments_scaled: Vec<Fragment> = fragments + let fragments_scaled: Vec<FragmentSpan> = fragments .into_iter() .map(|frag| frag.scale(settings.scale)) .collect(); diff --git a/packages/svgbob/src/buffer/cell_buffer/contacts.rs b/packages/svgbob/src/buffer/cell_buffer/contacts.rs index cad571c..33b4525 100644 --- a/packages/svgbob/src/buffer/cell_buffer/contacts.rs +++ b/packages/svgbob/src/buffer/cell_buffer/contacts.rs @@ -1,5 +1,6 @@ use super::endorse; use crate::buffer::fragment_buffer::FragmentSpan; +use crate::buffer::Span; use crate::buffer::{fragment::Fragment, Cell}; use std::fmt; @@ -33,6 +34,12 @@ impl Contacts { self.0.iter().flat_map(|fs| fs.cells()).collect() } + pub fn span(&self) -> Span { + let cell_chars: Vec<(Cell, char)> = + self.0.iter().flat_map(|fs| fs.span.0.clone()).collect(); + cell_chars.into() + } + /// Check if any fragment can be group with any of the other fragment /// We use `.rev()` on this list of fragment since it has a high change of matching at the last /// added fragment of the next fragments to be checked. @@ -105,12 +112,15 @@ impl Contacts { /// These includes: rect, roundedrect, pub(crate) fn endorse_rects( groups: Vec<Contacts>, - ) -> (Vec<Fragment>, Vec<Contacts>) { + ) -> (Vec<FragmentSpan>, Vec<Contacts>) { let mut fragments = vec![]; let mut un_endorsed_rect: Vec<Contacts> = vec![]; for group in groups { if let Some(fragment) = group.endorse_rect() { - fragments.push(fragment); + log::info!("got some endoresed rect.."); + let span = group.span(); + let fragment_span = FragmentSpan::new(span, fragment); + fragments.push(fragment_span); } else { un_endorsed_rect.push(group); } diff --git a/packages/svgbob/src/buffer/cell_buffer/span.rs b/packages/svgbob/src/buffer/cell_buffer/span.rs index af2ee7b..bcbd70b 100644 --- a/packages/svgbob/src/buffer/cell_buffer/span.rs +++ b/packages/svgbob/src/buffer/cell_buffer/span.rs @@ -1,3 +1,4 @@ +use crate::buffer::fragment_buffer::FragmentSpan; use crate::{ buffer::{ cell_buffer::Contacts, FragmentBuffer, Property, PropertyBuffer, @@ -15,7 +16,7 @@ use std::{ /// A describes where a char came from relative to the source ascii text /// The primary purpose of span is to group adjacent cell together -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct Span(pub Vec<(Cell, char)>); impl Deref for Span { @@ -162,14 +163,16 @@ impl Span { pub(crate) fn endorse( self, settings: &Settings, - ) -> (Vec<Fragment>, Vec<Contacts>) { + ) -> (Vec<FragmentSpan>, Vec<Contacts>) { let mut fragments = vec![]; let (top_left, _) = self.bounds().expect("must have bounds"); let un_endorsed_span = if let Some((circle, un_endorsed_span)) = circle_map::endorse_circle_span(&self) { let circle = circle.absolute_position(top_left); - fragments.push(circle.into()); + let circle_frag_span = + FragmentSpan::new(self.clone(), circle.into()); + fragments.push(circle_frag_span); un_endorsed_span } /*else if let Some((arc, un_endorsed_span)) = @@ -183,7 +186,8 @@ impl Span { circle_map::endorse_quarter_arc_span(&self) { let arc = arc.absolute_position(top_left); - fragments.push(arc.into()); + let arc_frag_span = FragmentSpan::new(self.clone(), arc.into()); + fragments.push(arc_frag_span); un_endorsed_span } else { self diff --git a/packages/svgbob/src/buffer/fragment_buffer.rs b/packages/svgbob/src/buffer/fragment_buffer.rs index 5b9a07a..53a81b0 100644 --- a/packages/svgbob/src/buffer/fragment_buffer.rs +++ b/packages/svgbob/src/buffer/fragment_buffer.rs @@ -108,7 +108,8 @@ impl FragmentBuffer { ch: char, fragment: Fragment, ) { - if let Some((_ch, existing)) = self.get_mut(&cell) { + if let Some((ex_ch, existing)) = self.get_mut(&cell) { + assert_eq!(*ex_ch, ch); existing.push(fragment); } else { self.insert(cell, (ch, vec![fragment])); @@ -123,7 +124,8 @@ impl FragmentBuffer { ch: char, fragments: Vec<Fragment>, ) { - if let Some((_ch, existing)) = self.get_mut(&cell) { + if let Some((ex_ch, existing)) = self.get_mut(&cell) { + assert_eq!(*ex_ch, ch); existing.extend(fragments); } else { self.insert(cell, (ch, fragments)); diff --git a/packages/svgbob/src/buffer/fragment_buffer/fragment_span.rs b/packages/svgbob/src/buffer/fragment_buffer/fragment_span.rs index 917fd38..8a9ab0c 100644 --- a/packages/svgbob/src/buffer/fragment_buffer/fragment_span.rs +++ b/packages/svgbob/src/buffer/fragment_buffer/fragment_span.rs @@ -25,6 +25,13 @@ impl FragmentSpan { self.span.0.iter().map(|(cell, _ch)| *cell).collect() } + pub fn scale(&self, scale: f32) -> Self { + Self { + span: self.span.clone(), + fragment: self.fragment.scale(scale), + } + } + pub fn merge(&self, other: &Self, settings: &Settings) -> Option<Self> { if let Some(new_merge) = self.fragment.merge(&other.fragment, settings) { @@ -85,4 +92,12 @@ impl FragmentSpan { fragment: self.fragment.absolute_position(cell), } } + + pub fn is_bounded(&self, bound1: Cell, bound2: Cell) -> bool { + self.span.is_bounded(bound1, bound2) + } + + pub fn hit_cell(&self, needle: Cell) -> bool { + self.span.hit_cell(needle) + } } diff --git a/packages/svgbob/src/buffer/fragment_buffer/fragment_tree.rs b/packages/svgbob/src/buffer/fragment_buffer/fragment_tree.rs index 714beba..99b1b2e 100644 --- a/packages/svgbob/src/buffer/fragment_buffer/fragment_tree.rs +++ b/packages/svgbob/src/buffer/fragment_buffer/fragment_tree.rs @@ -1,3 +1,4 @@ +use crate::buffer::fragment_buffer::FragmentSpan; use crate::Fragment; use sauron::{html::attributes::*, Node}; @@ -6,15 +7,15 @@ use sauron::{html::attributes::*, Node}; /// The main purpose of this struct is for tagging fragments /// such as rect and circles to have a CellText fragment inside that are special /// text commands such as css classes, which the user can style the containing fragment -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] pub struct FragmentTree { - fragment: Fragment, + fragment: FragmentSpan, css_tag: Vec<String>, enclosing: Vec<FragmentTree>, } impl FragmentTree { - pub(crate) fn new(fragment: Fragment) -> Self { + pub(crate) fn new(fragment: FragmentSpan) -> Self { FragmentTree { fragment, css_tag: vec![], @@ -23,7 +24,7 @@ impl FragmentTree { } fn can_fit(&self, other: &Self) -> bool { - self.fragment.can_fit(&other.fragment) + self.fragment.fragment.can_fit(&other.fragment.fragment) } /// check if this fragment can fit to this fragment tree. @@ -53,7 +54,7 @@ impl FragmentTree { } } if self.can_fit(other) { - let css_tags = other.fragment.as_css_tag(); + let css_tags = other.fragment.fragment.as_css_tag(); if !css_tags.is_empty() { self.css_tag.extend(css_tags); } else { @@ -65,7 +66,7 @@ impl FragmentTree { } } - pub(crate) fn enclose_fragments(fragments: Vec<Fragment>) -> Vec<Self> { + pub(crate) fn enclose_fragments(fragments: Vec<FragmentSpan>) -> Vec<Self> { let fragment_trees: Vec<Self> = fragments .into_iter() .map(|frag| FragmentTree::new(frag)) @@ -101,7 +102,7 @@ impl FragmentTree { /// convert back into fragments fn into_nodes<MSG>(self) -> Vec<Node<MSG>> { let mut nodes = vec![]; - let mut fragment_node: Node<MSG> = self.fragment.into(); + let mut fragment_node: Node<MSG> = self.fragment.fragment.into(); let _css_tag_len = self.css_tag.len(); fragment_node = fragment_node.merge_attributes(vec![classes(self.css_tag)]); @@ -116,7 +117,7 @@ impl FragmentTree { /// convert fragments to node, where cell_text and text may become /// css class of the contain fragment pub(crate) fn fragments_to_node<MSG>( - fragments: Vec<Fragment>, + fragments: Vec<FragmentSpan>, ) -> Vec<Node<MSG>> { let fragment_trees: Vec<FragmentTree> = Self::enclose_fragments(fragments); diff --git a/packages/svgbob/src/lib.rs b/packages/svgbob/src/lib.rs index 8874f29..c01635a 100644 --- a/packages/svgbob/src/lib.rs +++ b/packages/svgbob/src/lib.rs @@ -10,7 +10,7 @@ pub mod util; pub use buffer::{ fragment, fragment::Fragment, Cell, CellBuffer, Direction, FragmentBuffer, - Property, Signal, + FragmentSpan, Property, Signal, }; pub use nalgebra; pub use point::Point; |