summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJovansonlee Cesar <ivanceras@gmail.com>2020-11-25 16:53:19 +0800
committerJovansonlee Cesar <ivanceras@gmail.com>2020-11-25 16:53:19 +0800
commitdcd65f2361f88b7cbc9e81b91382f21c60114706 (patch)
tree17bae69413c2df41c8e5061a7955880fd41aed52
parent4af1321cb8126ed2d749e4fdb862e9e47bb1ae87 (diff)
Reimplement merging of line and arrow_head + diamond
-rw-r--r--svgbob/src/buffer/fragment_buffer.rs12
-rw-r--r--svgbob/src/buffer/fragment_buffer/direction.rs4
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment.rs86
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/line.rs47
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/polygon.rs49
-rw-r--r--svgbob/src/map/ascii_map.rs14
-rw-r--r--svgbob/src/map/unicode_map.rs25
-rw-r--r--svgbob/test_data/merge.bob68
8 files changed, 202 insertions, 103 deletions
diff --git a/svgbob/src/buffer/fragment_buffer.rs b/svgbob/src/buffer/fragment_buffer.rs
index a7bda18..39846f5 100644
--- a/svgbob/src/buffer/fragment_buffer.rs
+++ b/svgbob/src/buffer/fragment_buffer.rs
@@ -130,12 +130,8 @@ 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 mfrag.can_merge(&abs_frag) {
- if let Some(new_merge) = mfrag.merge(&abs_frag) {
- *mfrag = new_merge;
- } else {
- panic!("Should merged");
- }
+ if let Some(new_merge) = mfrag.merge(&abs_frag) {
+ *mfrag = new_merge;
true
} else {
false
@@ -163,8 +159,8 @@ impl FragmentBuffer {
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 new_frag.can_merge(&fragment) {
- *new_frag = new_frag.merge(&fragment).expect("should merge");
+ if let Some(new_merged) = new_frag.merge(&fragment) {
+ *new_frag = new_merged;
true
} else {
false
diff --git a/svgbob/src/buffer/fragment_buffer/direction.rs b/svgbob/src/buffer/fragment_buffer/direction.rs
index 25ec3db..3eedaa8 100644
--- a/svgbob/src/buffer/fragment_buffer/direction.rs
+++ b/svgbob/src/buffer/fragment_buffer/direction.rs
@@ -1,7 +1,7 @@
use crate::buffer::CellGrid;
use crate::fragment::PolygonTag;
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Copy)]
pub enum Direction {
TopLeft,
Top,
@@ -27,6 +27,7 @@ impl Direction {
Direction::BottomRight => Direction::TopLeft,
}
}
+ /*
pub(crate) fn any_along_side(&self, tags: &[PolygonTag]) -> bool {
tags.iter().any(|tag| self.is_along_side(tag))
}
@@ -60,6 +61,7 @@ impl Direction {
},
}
}
+ */
/// calculate the threshold length which is the basis
/// if the arrow and the line is connected
diff --git a/svgbob/src/buffer/fragment_buffer/fragment.rs b/svgbob/src/buffer/fragment_buffer/fragment.rs
index dd62235..7fd5cb9 100644
--- a/svgbob/src/buffer/fragment_buffer/fragment.rs
+++ b/svgbob/src/buffer/fragment_buffer/fragment.rs
@@ -97,52 +97,6 @@ impl Fragment {
}
}
- /// check if 2 fragments can merge into one
- /// FIXME: This is only merging lines and text right now
- pub fn can_merge(&self, other: &Self) -> bool {
- match (self, other) {
- // line and line
- (Fragment::Line(line), Fragment::Line(other_line)) => line.can_merge(other_line),
-
- /*
- // line and polygon
- (Fragment::Line(line), Fragment::Polygon(polygon)) => line.can_merge_polygon(polygon),
-
- // polygon and line
- (Fragment::Polygon(polygon), Fragment::Line(line)) => line.can_merge_polygon(polygon),
- */
-
- /*
- // line and marker_line
- (Fragment::Line(line), Fragment::MarkerLine(mline)) => {
- line.can_merge_marker_line(mline)
- }
-
- // marker_line and line
- (Fragment::MarkerLine(mline), Fragment::Line(line)) => {
- line.can_merge_marker_line(mline)
- }
- (Fragment::MarkerLine(mline), Fragment::Polygon(polygon)) => {
- mline.can_merge_polygon(polygon)
- }
- */
-
- //TODO: make a function level2 merge where it merges fragments into
- // marker_lines
- /*
- // line and circle
- (Fragment::Line(line), Fragment::Circle(circle)) => line.can_merge_circle(circle),
- // circle and line
- (Fragment::Circle(circle), Fragment::Line(line)) => line.can_merge_circle(circle),
- */
- // cell_text and cell_text
- (Fragment::CellText(ctext), Fragment::CellText(other_ctext)) => {
- ctext.can_merge(other_ctext)
- }
- _ => false,
- }
- }
-
/// FIXME: This is only merging lines and text right now
pub fn merge(&self, other: &Self) -> Option<Self> {
match (self, other) {
@@ -155,13 +109,11 @@ impl Fragment {
}
}
- /*
// line and polygon
(Fragment::Line(line), Fragment::Polygon(polygon)) => line.merge_line_polygon(polygon),
// polygon and line
(Fragment::Polygon(polygon), Fragment::Line(line)) => line.merge_line_polygon(polygon),
- */
/*
// line and marker_line
@@ -214,8 +166,8 @@ impl Fragment {
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 new_group.can_merge(&fragment) {
- *new_group = new_group.merge(&fragment).expect("must merge");
+ if let Some(new_merged) = new_group.merge(&fragment) {
+ *new_group = new_merged;
true
} else {
false
@@ -673,9 +625,37 @@ mod tests {
let n = CellGrid::n();
let o = CellGrid::o();
let j = CellGrid::j();
- assert!(line(k, m).can_merge(&line(m, o))); // collinear and connected
- assert!(!line(k, l).can_merge(&line(n, o))); //collinear but not connected
- assert!(!line(k, o).can_merge(&line(o, j))); // connected but not collinear
+ 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
+ }
+
+ #[test]
+ fn merge_unicode_triangle_and_line() {
+ let arrow = '▶';
+ let entry = crate::map::UNICODE_FRAGMENTS
+ .get(&arrow)
+ .expect("must have a fragement");
+ let a = CellGrid::a();
+ let y = CellGrid::y();
+
+ let polygon = entry[0].absolute_position(Cell::new(0, 0));
+ let diagonal: Fragment = Line::new_noswap(y, a, false).into();
+ let diagonal = diagonal.absolute_position(Cell::new(1, 1));
+
+ println!("polygon: {:#?}", polygon);
+ println!("diagonal: {:#?}", diagonal);
+
+ let merged = polygon.merge(&diagonal);
+
+ let expected = marker_line(
+ Point::new(2.0, 4.0),
+ Point::new(0.0, 0.0),
+ false,
+ None,
+ Some(Marker::Arrow),
+ );
+ assert_eq!(Some(expected), merged);
}
#[test]
diff --git a/svgbob/src/buffer/fragment_buffer/fragment/line.rs b/svgbob/src/buffer/fragment_buffer/fragment/line.rs
index c060f97..7fe37cf 100644
--- a/svgbob/src/buffer/fragment_buffer/fragment/line.rs
+++ b/svgbob/src/buffer/fragment_buffer/fragment/line.rs
@@ -308,29 +308,20 @@ impl Line {
// check also if the distance of this line end-point to the center
// of the polygon is less than the diagonal width of the cell grid.
let poly_center = polygon.center();
+
+ println!("poly_center: {:?}", poly_center);
let distance_end_center = self.end.distance(&poly_center);
let distance_start_center = self.start.distance(&poly_center);
- let threshold_length = self.heading().threshold_length();
- let is_close_start_point = distance_start_center < threshold_length;
- let is_close_end_point = distance_end_center < threshold_length;
-
- let direction = polygon.tags.get(0).map(|tag| tag.direction()).flatten();
+ let threshold_length = dbg!(self.heading().threshold_length());
+ let is_close_start_point = dbg!(distance_start_center < threshold_length);
+ let is_close_end_point = dbg!(distance_end_center < threshold_length);
- let is_same_direction = polygon
- .tags
- .iter()
- .any(|tag| tag.matched_direction(self.heading()));
+ let is_same_direction = dbg!(polygon.matched_direction(self.heading()));
- //TODO: deal with merging with the opposite direction
- /*
- let is_opposite = polygon
- .tags
- .iter()
- .any(|tag| tag.matched_direction(self.heading().opposite()));
- */
+ let is_opposite_direction = dbg!(polygon.matched_direction(self.heading().opposite()));
- is_same_direction && (is_close_start_point || is_close_end_point)
+ (is_same_direction || is_opposite_direction) && (is_close_start_point || is_close_end_point)
}
/// TODO: the get_marker function don't take into account the direction
@@ -341,9 +332,7 @@ impl Line {
/// merge this line to the marker line
pub(crate) fn merge_line_polygon(&self, polygon: &Polygon) -> Option<Fragment> {
if self.can_merge_polygon(polygon) {
- let marker = polygon.tags.get(0).map(|tag| tag.get_marker());
- let direction = polygon.tags.get(0).map(|tag| tag.direction()).flatten();
- let heading = self.heading();
+ let marker = polygon.get_marker();
let poly_center = polygon.center();
let distance_end_center = self.end.distance(&poly_center);
@@ -353,17 +342,9 @@ impl Line {
let is_close_start_point = distance_start_center < threshold_length;
let is_close_end_point = distance_end_center < threshold_length;
- let is_same_direction = polygon
- .tags
- .iter()
- .any(|tag| tag.matched_direction(self.heading()));
+ let is_same_direction = dbg!(polygon.matched_direction(self.heading()));
- let is_opposite = polygon
- .tags
- .iter()
- .any(|tag| tag.matched_direction(self.heading().opposite()));
-
- let is_diamond = Some(Marker::Diamond) == marker;
+ let is_opposite_direction = dbg!(polygon.matched_direction(self.heading().opposite()));
let new_line = if is_close_end_point {
Line::new_noswap(self.start, self.end, self.is_broken)
@@ -375,12 +356,6 @@ impl Line {
};
let mut extended_line = new_line.extend(threshold_length);
- //TODO: deal with the opposite direction
- /*
- if !is_diamond && is_opposite {
- extended_line.swap();
- }
- */
Some(marker_line(
extended_line.start,
extended_line.end,
diff --git a/svgbob/src/buffer/fragment_buffer/fragment/polygon.rs b/svgbob/src/buffer/fragment_buffer/fragment/polygon.rs
index dc0f1b3..7143584 100644
--- a/svgbob/src/buffer/fragment_buffer/fragment/polygon.rs
+++ b/svgbob/src/buffer/fragment_buffer/fragment/polygon.rs
@@ -1,5 +1,6 @@
use crate::Direction;
use crate::{
+ buffer::CellGrid,
fragment::{
marker_line::{Marker, MarkerLine},
Bounds,
@@ -90,6 +91,22 @@ impl PolygonTag {
true
}
}
+
+ /*
+ /// calculate the threshold length which is the basis
+ /// if the arrow and the line is connected
+ pub(crate) fn threshold_length(&self) -> f32 {
+ match self {
+ PolygonTag::ArrowTopRight
+ | PolygonTag::ArrowBottomRight
+ | PolygonTag::ArrowBottomLeft
+ | PolygonTag::ArrowTopLeft => CellGrid::diagonal_length(),
+ PolygonTag::ArrowBottom | PolygonTag::ArrowTop => CellGrid::height(),
+ PolygonTag::ArrowLeft | PolygonTag::ArrowRight => CellGrid::width(),
+ PolygonTag::DiamondBullet => CellGrid::diagonal_length(),
+ }
+ }
+ */
}
impl Polygon {
@@ -114,6 +131,38 @@ impl Polygon {
}
}
+ pub(crate) fn matched_direction(&self, direction: Direction) -> bool {
+ self.tags.iter().any(|tag| tag.matched_direction(direction))
+ }
+
+ fn is_diamond(&self) -> bool {
+ self.tags.len() == 1
+ && self
+ .tags
+ .iter()
+ .all(|tag| *tag == PolygonTag::DiamondBullet)
+ }
+
+ /// returns Diamond marker if the tags is a DiamondBullet
+ /// otherwise if it is an Arrow direction, then return Arrow.
+ pub(crate) fn get_marker(&self) -> Option<Marker> {
+ if !self.tags.is_empty() {
+ if self.is_diamond() {
+ Some(Marker::Diamond)
+ } else if self
+ .tags
+ .iter()
+ .all(|tag| tag.get_marker() == Marker::Arrow)
+ {
+ Some(Marker::Arrow)
+ } else {
+ None
+ }
+ } else {
+ None
+ }
+ }
+
pub(in crate) fn scale(&self, scale: f32) -> Self {
let points: Vec<Point> = self.points.iter().map(|p| p.scale(scale)).collect();
Polygon {
diff --git a/svgbob/src/map/ascii_map.rs b/svgbob/src/map/ascii_map.rs
index 3d6d404..c340b20 100644
--- a/svgbob/src/map/ascii_map.rs
+++ b/svgbob/src/map/ascii_map.rs
@@ -359,10 +359,18 @@ lazy_static! {
Arc::new(
move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
vec![
+ //
+ // | #
+ // # | --# #--
+ //
(top.line_overlap(r,w) || bottom.line_overlap(c,h)
|| left.line_overlap(n,o) || right.line_overlap(k,l),
vec![rect(f,t, true, false)]),
+ //
+ // \ # / #
+ // # \ # /
+ //
(top_left.line_overlap(s,y)|| bottom_right.line_overlap(a,g)
|| bottom_left.line_overlap(u,q) || top_right.line_overlap(e,i),
vec![polygon(vec![k,h,o,r,k],true, vec![DiamondBullet])]),
@@ -861,7 +869,7 @@ lazy_static! {
////////////////////////
('V',
vec![
- (Medium, vec![polygon(vec![f,j,w], true, vec![ArrowBottom])]),
+ (Medium, vec![polygon(vec![f,j,w], true, vec![ArrowBottom, ArrowBottomLeft, ArrowBottomRight])]),
(Weak, vec![line(m,w)]),
],
Arc::new(
@@ -895,7 +903,7 @@ lazy_static! {
////////////////////////
('v',
vec![
- (Medium, vec![polygon(vec![f,j,w], true, vec![ArrowBottom])]),
+ (Medium, vec![polygon(vec![f,j,w], true, vec![ArrowBottom, ArrowBottomLeft, ArrowBottomRight])]),
],
Arc::new(
move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
@@ -927,7 +935,7 @@ lazy_static! {
////////////////////////
('^',
vec![
- (Medium, vec![polygon(vec![p,c,t], true, vec![ArrowTop])]),
+ (Medium, vec![polygon(vec![p,c,t], true, vec![ArrowTop, ArrowTopLeft, ArrowTopRight])]),
],
Arc::new(
move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
diff --git a/svgbob/src/map/unicode_map.rs b/svgbob/src/map/unicode_map.rs
index bca9ef0..66afb73 100644
--- a/svgbob/src/map/unicode_map.rs
+++ b/svgbob/src/map/unicode_map.rs
@@ -162,10 +162,23 @@ lazy_static! {
('△', vec![line(c,y), line(y,u), line(u,c)]),
// arrow down matching v
+ //
+ // |
+ // ▾
('▾', vec![polygon(vec![f,j,w], true, vec![ArrowBottom])]),
+ //
+ // ▴
+ // |
('▴', vec![polygon(vec![p,c,t], true, vec![ArrowTop])]),
+ //
+ // --▸
+ //
('▸', vec![polygon(vec![f,o,p], true, vec![ArrowRight])]),
+ //
+ // ◂--
+ //
('◂', vec![polygon(vec![j,k,t], true, vec![ArrowLeft])]),
+
('◆', vec![polygon(vec![k,h,o,r,k], true, vec![DiamondBullet])]),
('▪', vec![rect(f,t,true, false)]),
@@ -186,9 +199,17 @@ lazy_static! {
// 8/8
('█', vec![rect(a,y,true,false)]),
+ // /
+ // --▶ ▶ ▶
+ // \
+ //
+ ('▶', vec![polygon(vec![f,o,p], true, vec![ArrowRight, ArrowTopLeft, ArrowBottomLeft])]),
- ('▶', vec![polygon(vec![f,o,p], true, vec![ArrowRight])]),
- ('◀', vec![polygon(vec![j,k,t], true, vec![ArrowLeft])]),
+ // \
+ // ◀-- ◀ ◀
+ // /
+ //
+ ('◀', vec![polygon(vec![j,k,t], true, vec![ArrowLeft, ArrowBottomRight, ArrowTopRight])]),
// L shape bottom-left box
diff --git a/svgbob/test_data/merge.bob b/svgbob/test_data/merge.bob
index 5f63a78..8770313 100644
--- a/svgbob/test_data/merge.bob
+++ b/svgbob/test_data/merge.bob
@@ -10,6 +10,74 @@
| ____
'--> /___/
+.-------.
+| Hello |
+'-------'
+ |
+ v
+.-------.
+| World |
+'-------'
+
+
+ |
+ v
+---------------->
+ |
+ |
+
+
+.----------. .----------.
+|{w} A |-->|{w} B |
+'----------' '----------'
+
+.----------. .----------.
+|{w} A |<--|{w} B |
+'----------' '----------'
+
+.----------. .----------.
+|{w} A |<->|{w} B |
+'----------' '----------'
+
+.~~~~~~~~~~~~~~~~~~~~.
+! ⛑️Problem Emoji :
+! ⛑️ Problem Emoji :
+! ⛑️ Problem Emoji :
+! ⛑️ Problem Emoji :
+'~~~~~~~~~~~~~~~~~~~~'
+
+
+<--+----+----+----+----+----+----+----+----+-->
+ | | | | | | | | |
+ "-4" "-3" "-2" "-1" "0" "+1" "+2" "+3" "+4"
+
+
+ *----.
+--+ ab |
+ | ab |
+--*----'
+ +
+
+
+
+
+ -------▸
+
+
+ ◂------
+
+
+ /
+ /
+ ---▶ ▶ ▶
+ \
+ \
+
+ \
+ \
+ ◀---- ◀ ◀
+ /
+ /
# ^ ^ # O ^