Skip to content

Commit

Permalink
Pass the settings to merge functions, so the user can opt to chose wh…
Browse files Browse the repository at this point in the history
…ether or not to allow mergin_line_with_shapes

Unify the merge_fragments in frament_buffer and fragment module
  • Loading branch information
ivanceras committed Jun 30, 2021
1 parent 963f51c commit 6258b91
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 71 deletions.
3 changes: 3 additions & 0 deletions svgbob/src/buffer/cell_buffer/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -45,6 +47,7 @@ impl Default for Settings {
include_backdrop: true,
include_styles: true,
include_defs: true,
merge_line_with_shapes: false,
}
}
}
2 changes: 1 addition & 1 deletion svgbob/src/buffer/cell_buffer/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl Span {
(&localize_self).into_fragment_buffer(settings);

let mut groups: Vec<Contacts> = 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) {
Expand Down
38 changes: 5 additions & 33 deletions svgbob/src/buffer/fragment_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,23 +121,23 @@ impl FragmentBuffer {
self.sort_fragments_in_cell(cell);
}

pub fn merge_fragments(&self) -> Vec<Fragment> {
let fragments = self.first_pass_merge();
Self::merge_recursive(fragments)
pub fn merge_fragments(&self, settings: &Settings) -> Vec<Fragment> {
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<Fragment> {
fn first_pass_merge(&self, settings: &Settings) -> Vec<Fragment> {
let mut merged: Vec<Fragment> = vec![];
for (cell, fragments) in self.iter() {
for frag in fragments.iter() {
//Note: The fragments are calculated with their absolute
// 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 {
Expand All @@ -151,32 +151,4 @@ impl FragmentBuffer {
}
merged
}

fn merge_recursive(fragments: Vec<Fragment>) -> Vec<Fragment> {
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<Fragment>) -> Vec<Fragment> {
let mut new_fragments: Vec<Fragment> = 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
}
}
92 changes: 66 additions & 26 deletions svgbob/src/buffer/fragment_buffer/fragment.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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<Self> {
pub fn merge(&self, other: &Self, settings: &Settings) -> Option<Self> {
match (self, other) {
// line and line
(Fragment::Line(line), Fragment::Line(other_line)) => {
Expand All @@ -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)) => {
Expand All @@ -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<Self>) -> Vec<Self> {
pub(crate) fn merge_recursive(
fragments: Vec<Self>,
settings: &Settings,
) -> Vec<Self> {
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<Self>) -> Vec<Self> {
fn second_pass_merge(
fragments: Vec<Self>,
settings: &Settings,
) -> Vec<Self> {
let mut new_groups: Vec<Self> = 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 {
Expand Down Expand Up @@ -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:");
Expand All @@ -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]
Expand All @@ -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),
Expand All @@ -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),
Expand Down
4 changes: 2 additions & 2 deletions svgbob/src/buffer/property_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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(
Expand Down
6 changes: 3 additions & 3 deletions svgbob/src/map/ascii_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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])]),
Expand Down Expand Up @@ -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])]),
Expand Down
12 changes: 6 additions & 6 deletions svgbob/test_data/example.bob
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ What can it do?
! / \ /\ \ \ o----> | ^ # / / :
! / \ / \ ) ) <----# | | ^ : / v :
! \ / \ / /_______/ v | ! : :
! \_______/ \/ o. o ! V :
! `.~~~~. :
! '. O :
! .-----------. . <. .> . '. ^ \ :
! ( ) ( ) ( ) : \ \ :
! '-----+ ,---' `> ' ` <' '.~~~~> \ v :
! \_______/ \/ o ! V :
! :
! O :
! .-----------. . <. .> . ^ \ :
! ( ) ( ) ( ) \ \ :
! '-----+ ,---' `> ' ` <' \ v :
! |/ * :
! ' _ __ :
! __ .-. .--. .--.--. .--. .' '. ,' '. :
Expand Down
48 changes: 48 additions & 0 deletions svgbob/test_data/simple.bob
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@




------>

<------

^
| |
| |
V

^ \ ^ /
\ \ / /
\ V / V


.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
! :
Expand Down Expand Up @@ -36,6 +46,44 @@
! !
`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'


.- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -.
! . :
! +------+ .------. .------. /\ .' `. :
! | | | | ( ) / \ .' `. ^ :
! +------+ '------' '------' '----' `. .' / # :
! _______ ________ # `.' / ^ / :
! / \ /\ \ \ o----> | ^ # / / :
! / \ / \ ) ) <----# | | ^ : / v :
! \ / \ / /_______/ v | ! : :
! \_______/ \/ o ! V :
! :
! O :
! .-----------. . <. .> . ^ \ :
! ( ) ( ) ( ) \ \ :
! '-----+ ,---' `> ' ` <' \ v :
! |/ * :
! ' _ __ :
! __ .-. .--. .--.--. .--. .' '. ,' '. :
! (_) (__) ( ) ( ) ( ( ) ) ( ) ( ) ( ) :
! '-' `--' `--'--' `--' `._.' `.__.' :
! !
! ___ ____ ____ _____ !
! ,' `. ,' `. .' `. ,' `. !
! / \ / \ / \ / \ !
! \ / \ / ( ) ( ) !
! `.___.' `.____.' \ / \ / !
! `.____.' `._____.' !
! ______ !
! ,' `. !
! / \ .-----. .----. ".--------------." !
! | | \ / \ \ "| Don't draw me|" !
! | | \ / \ \ "| |" !
! \ / ' '----' "'--------------'" !
! `.______.' !
! !
`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

# Legend:
r1 = {
fill: papayawhip;
Expand Down

0 comments on commit 6258b91

Please sign in to comment.