From 6258b919e17274975cb115139cce81796d10c7fd Mon Sep 17 00:00:00 2001 From: Jovansonlee Cesar Date: Wed, 30 Jun 2021 11:01:40 +0800 Subject: Pass the settings to merge functions, so the user can opt to chose whether or not to allow mergin_line_with_shapes Unify the merge_fragments in frament_buffer and fragment module --- svgbob/src/buffer/cell_buffer/settings.rs | 3 + svgbob/src/buffer/cell_buffer/span.rs | 2 +- svgbob/src/buffer/fragment_buffer.rs | 38 ++--------- svgbob/src/buffer/fragment_buffer/fragment.rs | 92 +++++++++++++++++++-------- svgbob/src/buffer/property_buffer.rs | 4 +- svgbob/src/map/ascii_map.rs | 6 +- svgbob/test_data/example.bob | 12 ++-- svgbob/test_data/simple.bob | 48 ++++++++++++++ 8 files changed, 134 insertions(+), 71 deletions(-) diff --git a/svgbob/src/buffer/cell_buffer/settings.rs b/svgbob/src/buffer/cell_buffer/settings.rs index 2db4f95..de4cb40 100644 --- a/svgbob/src/buffer/cell_buffer/settings.rs +++ b/svgbob/src/buffer/cell_buffer/settings.rs @@ -23,6 +23,8 @@ pub struct Settings { pub include_styles: bool, /// flag whether to include the def of markers, etc in the svg pub include_defs: bool, + /// merge lines and shapes like triangle,circle,rect to form arrow lines or marker line + pub merge_line_with_shapes: bool, } impl Settings { /// the inverse of the default scale 10 @@ -45,6 +47,7 @@ impl Default for Settings { include_backdrop: true, include_styles: true, include_defs: true, + merge_line_with_shapes: false, } } } diff --git a/svgbob/src/buffer/cell_buffer/span.rs b/svgbob/src/buffer/cell_buffer/span.rs index 8cbf2ab..dc8bb60 100644 --- a/svgbob/src/buffer/cell_buffer/span.rs +++ b/svgbob/src/buffer/cell_buffer/span.rs @@ -104,7 +104,7 @@ impl Span { (&localize_self).into_fragment_buffer(settings); let mut groups: Vec = vec![]; - let merged_fragments = fb.merge_fragments(); + let merged_fragments = fb.merge_fragments(settings); for fragment in merged_fragments.into_iter() { let belongs_to_group = groups.iter_mut().rev().any(|group| { if group.is_contacting_frag(&fragment) { diff --git a/svgbob/src/buffer/fragment_buffer.rs b/svgbob/src/buffer/fragment_buffer.rs index 0051b86..a550b0f 100644 --- a/svgbob/src/buffer/fragment_buffer.rs +++ b/svgbob/src/buffer/fragment_buffer.rs @@ -121,15 +121,15 @@ impl FragmentBuffer { self.sort_fragments_in_cell(cell); } - pub fn merge_fragments(&self) -> Vec { - let fragments = self.first_pass_merge(); - Self::merge_recursive(fragments) + pub fn merge_fragments(&self, settings: &Settings) -> Vec { + let fragments = self.first_pass_merge(settings); + Fragment::merge_recursive(fragments, settings) } /// merge fragments that can be merged. /// This is only merging the fragments that are in the same /// cell - fn first_pass_merge(&self) -> Vec { + fn first_pass_merge(&self, settings: &Settings) -> Vec { let mut merged: Vec = vec![]; for (cell, fragments) in self.iter() { for frag in fragments.iter() { @@ -137,7 +137,7 @@ impl FragmentBuffer { // parameters and is derived from the cell position let abs_frag = frag.absolute_position(*cell); let had_merged = merged.iter_mut().rev().any(|mfrag| { - if let Some(new_merge) = mfrag.merge(&abs_frag) { + if let Some(new_merge) = mfrag.merge(&abs_frag, settings) { *mfrag = new_merge; true } else { @@ -151,32 +151,4 @@ impl FragmentBuffer { } merged } - - fn merge_recursive(fragments: Vec) -> Vec { - let original_len = fragments.len(); - let merged = Self::second_pass_merge(fragments); - if merged.len() < original_len { - Self::merge_recursive(merged) - } else { - merged - } - } - - fn second_pass_merge(fragments: Vec) -> Vec { - let mut new_fragments: Vec = vec![]; - for fragment in fragments.into_iter() { - let is_merged = new_fragments.iter_mut().rev().any(|new_frag| { - if let Some(new_merged) = new_frag.merge(&fragment) { - *new_frag = new_merged; - true - } else { - false - } - }); - if !is_merged { - new_fragments.push(fragment); - } - } - new_fragments - } } diff --git a/svgbob/src/buffer/fragment_buffer/fragment.rs b/svgbob/src/buffer/fragment_buffer/fragment.rs index 6be2c77..e793e19 100644 --- a/svgbob/src/buffer/fragment_buffer/fragment.rs +++ b/svgbob/src/buffer/fragment_buffer/fragment.rs @@ -1,5 +1,5 @@ use crate::{buffer::Cell, map::unicode_map::FRAGMENTS_UNICODE, Point}; -pub use crate::{Property, Signal}; +pub use crate::{Property, Settings, Signal}; pub use arc::Arc; pub use circle::Circle; pub use line::Line; @@ -99,7 +99,7 @@ impl Fragment { /// merge this fragment to the other fragment if it is possible /// returns None if the fragment can not be merge - pub fn merge(&self, other: &Self) -> Option { + pub fn merge(&self, other: &Self, settings: &Settings) -> Option { match (self, other) { // line and line (Fragment::Line(line), Fragment::Line(other_line)) => { @@ -112,35 +112,61 @@ impl Fragment { // line and polygon (Fragment::Line(line), Fragment::Polygon(polygon)) => { - line.merge_line_polygon(polygon) + if settings.merge_line_with_shapes { + line.merge_line_polygon(polygon) + } else { + None + } } // polygon and line (Fragment::Polygon(polygon), Fragment::Line(line)) => { - line.merge_line_polygon(polygon) + if settings.merge_line_with_shapes { + line.merge_line_polygon(polygon) + } else { + None + } } - /* // line and marker_line - (Fragment::Line(line), Fragment::MarkerLine(mline)) => line.merge_marker_line(mline), - */ - /* + (Fragment::Line(line), Fragment::MarkerLine(mline)) => { + if settings.merge_line_with_shapes { + line.merge_marker_line(mline) + } else { + None + } + } // marker_line and line - (Fragment::MarkerLine(mline), Fragment::Line(line)) => line.merge_marker_line(mline), - */ - /* + (Fragment::MarkerLine(mline), Fragment::Line(line)) => { + if settings.merge_line_with_shapes { + line.merge_marker_line(mline) + } else { + None + } + } (Fragment::MarkerLine(mline), Fragment::Polygon(polygon)) => { - mline.merge_polygon(polygon) + if settings.merge_line_with_shapes { + mline.merge_polygon(polygon) + } else { + None + } } - */ // line and circle (Fragment::Line(line), Fragment::Circle(circle)) => { - line.merge_circle(circle) + if settings.merge_line_with_shapes { + line.merge_circle(circle) + } else { + None + } } // circle and line (Fragment::Circle(circle), Fragment::Line(line)) => { - line.merge_circle(circle) + if settings.merge_line_with_shapes { + line.merge_circle(circle) + } else { + None + } } // cell_text and cell_text (Fragment::CellText(ctext), Fragment::CellText(other_ctext)) => { @@ -165,23 +191,29 @@ impl Fragment { } /// merge fragments recursively until it hasn't changed the number of fragments - pub(crate) fn merge_recursive(fragments: Vec) -> Vec { + pub(crate) fn merge_recursive( + fragments: Vec, + settings: &Settings, + ) -> Vec { let original_len = fragments.len(); - let merged = Self::second_pass_merge(fragments); + let merged = Self::second_pass_merge(fragments, settings); // if has merged continue merging untila nothing can be merged if merged.len() < original_len { - Self::merge_recursive(merged) + Self::merge_recursive(merged, settings) } else { merged } } /// second pass merge is operating on fragments comparing to other spans - fn second_pass_merge(fragments: Vec) -> Vec { + fn second_pass_merge( + fragments: Vec, + settings: &Settings, + ) -> Vec { let mut new_groups: Vec = vec![]; for fragment in fragments.into_iter() { let is_merged = new_groups.iter_mut().rev().any(|new_group| { - if let Some(new_merged) = new_group.merge(&fragment) { + if let Some(new_merged) = new_group.merge(&fragment, settings) { *new_group = new_merged; true } else { @@ -682,7 +714,8 @@ mod tests { } let mut expected = vec![line(k, o), line(c, w)]; expected.sort(); - let mut merged_fragments1 = Fragment::merge_recursive(fragments1); + let mut merged_fragments1 = + Fragment::merge_recursive(fragments1, &Settings::default()); merged_fragments1.sort(); assert_eq!(merged_fragments1.len(), 2); println!("after merged:"); @@ -700,9 +733,12 @@ mod tests { let n = CellGrid::n(); let o = CellGrid::o(); let j = CellGrid::j(); - assert!(line(k, m).merge(&line(m, o)).is_some()); // collinear and connected - assert!(!line(k, l).merge(&line(n, o)).is_some()); //collinear but not connected - assert!(!line(k, o).merge(&line(o, j)).is_some()); // connected but not collinear + let mut settings = Settings::default(); + settings.merge_line_with_shapes = true; + + assert!(line(k, m).merge(&line(m, o), &settings).is_some()); // collinear and connected + assert!(!line(k, l).merge(&line(n, o), &settings).is_some()); //collinear but not connected + assert!(!line(k, o).merge(&line(o, j), &settings).is_some()); // connected but not collinear } #[test] @@ -720,8 +756,10 @@ mod tests { println!("polygon: {:#?}", polygon); println!("diagonal: {:#?}", diagonal); + let mut settings = Settings::default(); - let merged = polygon.merge(&diagonal); + settings.merge_line_with_shapes = true; + let merged = polygon.merge(&diagonal, &settings); let expected = marker_line( Point::new(2.0, 4.0), @@ -748,7 +786,9 @@ mod tests { println!("circle: {:#?}", circle); println!("diagonal: {:#?}", diagonal); - let merged = circle.merge(&diagonal); + let mut settings = Settings::default(); + settings.merge_line_with_shapes = true; + let merged = circle.merge(&diagonal, &settings); let expected = marker_line( Point::new(2.0, 4.0), diff --git a/svgbob/src/buffer/property_buffer.rs b/svgbob/src/buffer/property_buffer.rs index df94601..8d9551f 100644 --- a/svgbob/src/buffer/property_buffer.rs +++ b/svgbob/src/buffer/property_buffer.rs @@ -110,7 +110,7 @@ impl<'p> PropertyBuffer<'p> { bottom_right, ); let mut merged_behavioral_fragments = - Fragment::merge_recursive(behavioral_fragments); + Fragment::merge_recursive(behavioral_fragments, settings); merged_behavioral_fragments.sort(); merged_behavioral_fragments.dedup(); //assert!(merged_behavioral_fragments.is_sorted()); @@ -174,7 +174,7 @@ impl<'p> PropertyBuffer<'p> { //If no match make it a text fragment if let Some(fragments) = UNICODE_FRAGMENTS.get(&property.ch) { let merged_fragments = - Fragment::merge_recursive(fragments.clone()); + Fragment::merge_recursive(fragments.clone(), settings); fb.add_fragments_to_cell(*cell, merged_fragments); } else { fb.add_fragment_to_cell( diff --git a/svgbob/src/map/ascii_map.rs b/svgbob/src/map/ascii_map.rs index cea3097..74dea1b 100644 --- a/svgbob/src/map/ascii_map.rs +++ b/svgbob/src/map/ascii_map.rs @@ -820,7 +820,7 @@ lazy_static! { vec![ // | // V - (top.line_overlap(r,w), vec![polygon(vec![f,j,w], true, vec![ArrowBottom])]), + (top.line_overlap(r,w), vec![polygon(vec![f,j,w], true, vec![ArrowBottom]), line(c,h)]), // \ // V // TODO: use arrow function which alias to a polygon @@ -853,7 +853,7 @@ lazy_static! { vec![ // | // v - (top.line_overlap(r,w), vec![polygon(vec![f,j,w], true, vec![ArrowBottom])]), + (top.line_overlap(r,w), vec![polygon(vec![f,j,w], true, vec![ArrowBottom]), line(c,h)]), // \ // v (top_left.line_overlap(s,y), vec![polygon(vec![f,s,_21], true, vec![ArrowBottomRight])]), @@ -885,7 +885,7 @@ lazy_static! { vec![ // ^ // | - (bottom.line_overlap(c,h), vec![polygon(vec![p,c,t], true, vec![ArrowTop])]), + (bottom.line_overlap(c,h), vec![polygon(vec![p,c,t], true, vec![ArrowTop]),line(r,w)]), // ^ // \ (bottom_right.line_overlap(a,g) &&!bottom_left.is('/'), vec![polygon(vec![t,g,_27], true, vec![ArrowTopLeft])]), diff --git a/svgbob/test_data/example.bob b/svgbob/test_data/example.bob index 646bc48..d05ca65 100644 --- a/svgbob/test_data/example.bob +++ b/svgbob/test_data/example.bob @@ -25,12 +25,12 @@ What can it do? ! / \ /\ \ \ o----> | ^ # / / : ! / \ / \ ) ) <----# | | ^ : / v : ! \ / \ / /_______/ v | ! : : - ! \_______/ \/ o. o ! V : - ! `.~~~~. : - ! '. O : - ! .-----------. . <. .> . '. ^ \ : - ! ( ) ( ) ( ) : \ \ : - ! '-----+ ,---' `> ' ` <' '.~~~~> \ v : + ! \_______/ \/ o ! V : + ! : + ! O : + ! .-----------. . <. .> . ^ \ : + ! ( ) ( ) ( ) \ \ : + ! '-----+ ,---' `> ' ` <' \ v : ! |/ * : ! ' _ __ : ! __ .-. .--. .--.--. .--. .' '. ,' '. : diff --git a/svgbob/test_data/simple.bob b/svgbob/test_data/simple.bob index bec0f56..256dd4a 100644 --- a/svgbob/test_data/simple.bob +++ b/svgbob/test_data/simple.bob @@ -1,10 +1,20 @@ + ------> <------ + ^ + | | + | | + V + + ^ \ ^ / + \ \ / / + \ V / V + .~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~. ! : @@ -36,6 +46,44 @@ ! ! `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' + + .- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -. + ! . : + ! +------+ .------. .------. /\ .' `. : + ! | | | | ( ) / \ .' `. ^ : + ! +------+ '------' '------' '----' `. .' / # : + ! _______ ________ # `.' / ^ / : + ! / \ /\ \ \ o----> | ^ # / / : + ! / \ / \ ) ) <----# | | ^ : / v : + ! \ / \ / /_______/ v | ! : : + ! \_______/ \/ o ! V : + ! : + ! O : + ! .-----------. . <. .> . ^ \ : + ! ( ) ( ) ( ) \ \ : + ! '-----+ ,---' `> ' ` <' \ v : + ! |/ * : + ! ' _ __ : + ! __ .-. .--. .--.--. .--. .' '. ,' '. : + ! (_) (__) ( ) ( ) ( ( ) ) ( ) ( ) ( ) : + ! '-' `--' `--'--' `--' `._.' `.__.' : + ! ! + ! ___ ____ ____ _____ ! + ! ,' `. ,' `. .' `. ,' `. ! + ! / \ / \ / \ / \ ! + ! \ / \ / ( ) ( ) ! + ! `.___.' `.____.' \ / \ / ! + ! `.____.' `._____.' ! + ! ______ ! + ! ,' `. ! + ! / \ .-----. .----. ".--------------." ! + ! | | \ / \ \ "| Don't draw me|" ! + ! | | \ / \ \ "| |" ! + ! \ / ' '----' "'--------------'" ! + ! `.______.' ! + ! ! + `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' + # Legend: r1 = { fill: papayawhip; -- cgit v1.2.3