summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJovansonlee Cesar <ivanceras@gmail.com>2020-02-13 20:11:14 +0800
committerJovansonlee Cesar <ivanceras@gmail.com>2020-02-13 20:11:14 +0800
commit0f35cd092e8b9e667d8f17f7dab47e923f7b3d82 (patch)
treef8556e9d8146a8437bf03dccff8efc687cb084b4
parent4c18492640cebcef566d95370598d239de556e3e (diff)
Pass Settings to the property, so behavior can be dependent on flags that is set in the settings
-rw-r--r--svgbob/src/buffer/cell_buffer.rs2
-rw-r--r--svgbob/src/buffer/cell_buffer/span.rs115
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/text.rs73
-rw-r--r--svgbob/src/buffer/property_buffer.rs66
-rw-r--r--svgbob/src/buffer/property_buffer/property.rs58
-rw-r--r--svgbob/src/map/ascii_map.rs58
-rw-r--r--svgbob/src/map/circle_map.rs39
7 files changed, 266 insertions, 145 deletions
diff --git a/svgbob/src/buffer/cell_buffer.rs b/svgbob/src/buffer/cell_buffer.rs
index f60a79b..aa20104 100644
--- a/svgbob/src/buffer/cell_buffer.rs
+++ b/svgbob/src/buffer/cell_buffer.rs
@@ -155,7 +155,7 @@ impl CellBuffer {
let (vec_fragments, vec_contacts): (Vec<Vec<Fragment>>, Vec<Vec<Contacts>>) = self
.group_adjacents()
.into_iter()
- .map(|span| span.endorse())
+ .map(|span| span.endorse(settings))
.unzip();
// partition the vec_groups into groups that is alone and the group
diff --git a/svgbob/src/buffer/cell_buffer/span.rs b/svgbob/src/buffer/cell_buffer/span.rs
index e9dd29e..c4adfe5 100644
--- a/svgbob/src/buffer/cell_buffer/span.rs
+++ b/svgbob/src/buffer/cell_buffer/span.rs
@@ -7,7 +7,7 @@ use crate::{
fragment,
fragment::{Circle, Marker},
map::{circle_map, UNICODE_FRAGMENTS},
- Cell, Fragment,
+ Cell, Fragment, Settings,
};
use itertools::Itertools;
use std::{
@@ -40,16 +40,20 @@ impl Span {
}
pub(super) fn is_adjacent(&self, cell: &Cell) -> bool {
- self.iter().rev().any(|(ex_cell, _)| ex_cell.is_adjacent(cell))
+ self.iter()
+ .rev()
+ .any(|(ex_cell, _)| ex_cell.is_adjacent(cell))
}
/// if any cell of this span is adjacent to any cell of the other
/// Use .rev() to check the last cell of this Span agains the first cell of the other Span
/// They have a high change of matching faster
pub(super) fn can_merge(&self, other: &Self) -> bool {
- self.iter()
- .rev()
- .any(|(cell, _)| other.iter().any(|(other_cell, _)| cell.is_adjacent(other_cell)))
+ self.iter().rev().any(|(cell, _)| {
+ other
+ .iter()
+ .any(|(other_cell, _)| cell.is_adjacent(other_cell))
+ })
}
pub(super) fn merge(&mut self, other: &Self) {
@@ -93,9 +97,9 @@ impl Span {
/// Only elements on the same span are checked to see if they
/// belong on the same group
///
- pub(crate) fn get_contacts(self) -> Vec<Contacts> {
+ pub(crate) fn get_contacts(self, settings: &Settings) -> Vec<Contacts> {
let localize_self = self.localize();
- let fb: FragmentBuffer = (&localize_self).into();
+ let fb: FragmentBuffer = (&localize_self).into_fragment_buffer(settings);
let mut groups: Vec<Contacts> = vec![];
let merged_fragments = fb.merge_fragments();
@@ -120,7 +124,11 @@ impl Span {
let grouped = Self::second_pass_groupable(groups);
// continue calling group recursive until the original len
// has not decreased
- if grouped.len() < original_len { Self::group_recursive(grouped) } else { grouped }
+ if grouped.len() < original_len {
+ Self::group_recursive(grouped)
+ } else {
+ grouped
+ }
}
fn second_pass_groupable(groups: Vec<Contacts>) -> Vec<Contacts> {
@@ -192,9 +200,9 @@ impl Span {
/// 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) -> (Vec<Fragment>, Vec<Contacts>) {
+ pub(crate) fn endorse(self, settings: &Settings) -> (Vec<Fragment>, Vec<Contacts>) {
let (top_left, _) = self.bounds().expect("mut have bounds");
- let groups: Vec<Contacts> = self.get_contacts();
+ let groups: Vec<Contacts> = self.get_contacts(settings);
// 1st phase, successful_endorses fragments, unendorsed one)
let (mut fragments, mut un_endorsed) = Self::endorse_rects(groups);
// 2nd phase, try to endorse to circles and arcs from the rejects of the 1st phase
@@ -202,8 +210,14 @@ impl Span {
fragments.extend(circle_fragments);
(
- fragments.iter().map(|frag| frag.absolute_position(top_left)).collect(),
- un_endorsed.iter().map(|group| group.absolute_position(top_left)).collect(),
+ fragments
+ .iter()
+ .map(|frag| frag.absolute_position(top_left))
+ .collect(),
+ un_endorsed
+ .iter()
+ .map(|group| group.absolute_position(top_left))
+ .collect(),
)
}
@@ -224,7 +238,7 @@ impl<'p> Into<PropertyBuffer<'p>> for &Span {
let mut pb = PropertyBuffer::new();
for (cell, ch) in self.iter() {
if let Some(property) = Property::from_char(*ch) {
- pb.insert(*cell, property);
+ pb.as_mut().insert(*cell, property);
} else {
}
}
@@ -237,12 +251,12 @@ impl<'p> Into<PropertyBuffer<'p>> for &Span {
///
/// If a character has no property, try to see if has equivalent fragments from unicode_map
/// otherwise add it to the fragment_buffer as a text fragment
-impl Into<FragmentBuffer> for &Span {
- fn into(self) -> FragmentBuffer {
+impl Span {
+ fn into_fragment_buffer(&self, settings: &Settings) -> FragmentBuffer {
let pb: PropertyBuffer = self.into();
- let mut fb: FragmentBuffer = (&pb).into();
+ let mut fb: FragmentBuffer = pb.into_fragment_buffer(settings);
for (cell, ch) in self.iter() {
- if pb.get(cell).is_none() {
+ if pb.as_ref().get(cell).is_none() {
if let Some(fragments) = UNICODE_FRAGMENTS.get(ch) {
fb.add_fragments_to_cell(*cell, fragments.clone());
} else {
@@ -254,7 +268,6 @@ impl Into<FragmentBuffer> for &Span {
}
}
-
impl fmt::Display for Span {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut buffer = StringBuffer::new();
@@ -281,8 +294,6 @@ mod tests {
Point,
};
-
-
#[test]
fn test_bounds() {
let art = r#"
@@ -334,14 +345,18 @@ mod tests {
let span = adjacents.remove(0);
let (top_left, _) = span.bounds().unwrap();
assert_eq!(top_left, Cell::new(0, 1));
- let groups: Vec<Contacts> = span.get_contacts();
+ let groups: Vec<Contacts> = span.get_contacts(&Settings::default());
for (i, group) in groups.iter().enumerate() {
println!("group {} is: \n{}", i, group);
}
assert_eq!(groups.len(), 1);
let rect = groups[0].endorse_rects().unwrap();
- let expected =
- Fragment::Rect(Rect::new(Point::new(0.5, 1.0), Point::new(9.5, 5.0), false, false));
+ let expected = Fragment::Rect(Rect::new(
+ Point::new(0.5, 1.0),
+ Point::new(9.5, 5.0),
+ false,
+ false,
+ ));
assert_eq!(rect, expected);
}
@@ -369,8 +384,9 @@ mod tests {
let (bound2, _) = span2.bounds().unwrap();
assert_eq!(bound1, Cell::new(0, 1));
assert_eq!(bound2, Cell::new(0, 5));
- let groups1: Vec<Contacts> = span1.get_contacts();
- let groups2: Vec<Contacts> = span2.get_contacts();
+ let settings = &Settings::default();
+ let groups1: Vec<Contacts> = span1.get_contacts(settings);
+ let groups2: Vec<Contacts> = span2.get_contacts(settings);
assert_eq!(groups1.len(), 1);
assert_eq!(groups2.len(), 1);
@@ -378,11 +394,21 @@ mod tests {
let rect2 = groups2[0].endorse_rects().unwrap();
assert_eq!(
rect1,
- Fragment::Rect(Rect::new(Point::new(0.5, 1.0), Point::new(9.5, 5.0), false, false))
+ Fragment::Rect(Rect::new(
+ Point::new(0.5, 1.0),
+ Point::new(9.5, 5.0),
+ false,
+ false
+ ))
);
assert_eq!(
rect2,
- Fragment::Rect(Rect::new(Point::new(0.5, 1.0), Point::new(9.5, 5.0), false, false))
+ Fragment::Rect(Rect::new(
+ Point::new(0.5, 1.0),
+ Point::new(9.5, 5.0),
+ false,
+ false
+ ))
);
}
@@ -405,7 +431,7 @@ mod tests {
let span1 = spans.remove(0);
let (bound1, _) = span1.bounds().unwrap();
assert_eq!(bound1, Cell::new(0, 1));
- let groups: Vec<Contacts> = span1.get_contacts();
+ let groups: Vec<Contacts> = span1.get_contacts(&Settings::default());
assert_eq!(groups.len(), 2);
let rect1 = groups[0].endorse_rects().unwrap();
@@ -447,13 +473,16 @@ mod tests {
let span = adjacents.remove(0);
let (top_left, _) = span.bounds().unwrap();
assert_eq!(top_left, Cell::new(8, 1));
- let (mut fragments, _groups) = span.endorse();
+ let (mut fragments, _groups) = span.endorse(&Settings::default());
for (i, frag) in fragments.iter().enumerate() {
println!("frag {}:\n{}", i, frag);
}
assert_eq!(fragments.len(), 1);
let circle = fragments.remove(0);
- assert_eq!(circle, Fragment::Circle(Circle::new(Point::new(11.0, 5.0), 2.5, false)));
+ assert_eq!(
+ circle,
+ Fragment::Circle(Circle::new(Point::new(11.0, 5.0), 2.5, false))
+ );
}
#[test]
@@ -475,19 +504,27 @@ mod tests {
let span1 = adjacents.remove(0);
let (top_left1, _) = span1.bounds().unwrap();
assert_eq!(top_left1, Cell::new(8, 1));
- let (mut fragments, _groups) = span1.endorse();
+ let (mut fragments, _groups) = span1.endorse(&Settings::default());
assert_eq!(fragments.len(), 2);
let rect = fragments.remove(0);
assert!(rect.is_rect());
assert_eq!(
rect,
- Fragment::Rect(Rect::new(Point::new(9.5, 9.0), Point::new(19.5, 13.0), false, false))
+ Fragment::Rect(Rect::new(
+ Point::new(9.5, 9.0),
+ Point::new(19.5, 13.0),
+ false,
+ false
+ ))
);
let circle = fragments.remove(0);
assert!(circle.is_circle());
- assert_eq!(circle, Fragment::Circle(Circle::new(Point::new(11.0, 5.0), 2.5, false)));
+ assert_eq!(
+ circle,
+ Fragment::Circle(Circle::new(Point::new(11.0, 5.0), 2.5, false))
+ );
}
#[test]
@@ -515,13 +552,15 @@ mod tests {
let span1 = adjacents.remove(0);
let (top_left1, _) = span1.bounds().unwrap();
assert_eq!(top_left1, Cell::new(12, 3));
- let (mut fragments, _groups) = span1.endorse();
+ let (mut fragments, _groups) = span1.endorse(&Settings::default());
assert_eq!(fragments.len(), 1);
-
let circle = fragments.remove(0);
assert!(circle.is_circle());
- assert_eq!(circle, Fragment::Circle(Circle::new(Point::new(22.0, 17.0), 9.5, false)));
+ assert_eq!(
+ circle,
+ Fragment::Circle(Circle::new(Point::new(22.0, 17.0), 9.5, false))
+ );
}
#[test]
@@ -549,7 +588,7 @@ mod tests {
let span1 = adjacents.remove(0);
let (top_left1, _) = span1.bounds().unwrap();
assert_eq!(top_left1, Cell::new(12, 3));
- let (fragments, groups) = span1.endorse();
+ let (fragments, groups) = span1.endorse(&Settings::default());
assert_eq!(fragments.len(), 1);
assert_eq!(groups.len(), 1);
for (i, fragment) in groups.iter().enumerate() {
@@ -580,7 +619,7 @@ mod tests {
let (top_left1, _br) = span1.bounds().unwrap();
assert_eq!(top_left1, Cell::new(8, 5));
- let groups1 = span1.get_contacts();
+ let groups1 = span1.get_contacts(&Settings::default());
let since = groups1[11].as_ref()[0].as_cell_text().unwrap();
assert_eq!(since.content, "since");
assert_eq!(since.start, Cell::new(20, 1));
diff --git a/svgbob/src/buffer/fragment_buffer/fragment/text.rs b/svgbob/src/buffer/fragment_buffer/fragment/text.rs
index e8a9b20..b5ce261 100644
--- a/svgbob/src/buffer/fragment_buffer/fragment/text.rs
+++ b/svgbob/src/buffer/fragment_buffer/fragment/text.rs
@@ -35,12 +35,16 @@ impl CellText {
}
fn is_adjacent_cell(&self, other_cell: Cell) -> bool {
- self.cells().into_iter().any(|cell| cell.y == other_cell.y && cell.is_adjacent(&other_cell))
+ self.cells()
+ .into_iter()
+ .any(|cell| cell.y == other_cell.y && cell.is_adjacent(&other_cell))
}
/// cell text is groupable when they are adjacent
pub(crate) fn is_contacting(&self, other: &Self) -> bool {
- self.cells().into_iter().any(|cell| other.is_adjacent_cell(cell))
+ self.cells()
+ .into_iter()
+ .any(|cell| other.is_adjacent_cell(cell))
}
/// text can merge if they are next to each other and at the same line
@@ -53,9 +57,15 @@ impl CellText {
pub(in crate) fn merge(&self, other: &Self) -> Option<Self> {
if self.can_merge(other) {
if self.start.x < other.start.x {
- Some(CellText::new(self.start, format!("{}{}", self.content, other.content)))
+ Some(CellText::new(
+ self.start,
+ format!("{}{}", self.content, other.content),
+ ))
} else {
- Some(CellText::new(other.start, format!("{}{}", other.content, self.content)))
+ Some(CellText::new(
+ other.start,
+ format!("{}{}", other.content, self.content),
+ ))
}
} else {
None
@@ -63,13 +73,19 @@ impl CellText {
}
pub(in crate) fn absolute_position(&self, cell: Cell) -> Self {
- CellText { start: Cell::new(self.start.x + cell.x, self.start.y + cell.y), ..self.clone() }
+ CellText {
+ start: Cell::new(self.start.x + cell.x, self.start.y + cell.y),
+ ..self.clone()
+ }
}
}
impl Bounds for CellText {
fn bounds(&self) -> (Point, Point) {
- (self.start.top_left_most(), self.end_cell().bottom_right_most())
+ (
+ self.start.top_left_most(),
+ self.end_cell().bottom_right_most(),
+ )
}
}
@@ -110,11 +126,17 @@ impl Text {
}
pub(in crate) fn absolute_position(&self, cell: Cell) -> Self {
- Text { start: cell.absolute_position(self.start), ..self.clone() }
+ Text {
+ start: cell.absolute_position(self.start),
+ ..self.clone()
+ }
}
pub(in crate) fn scale(&self, scale: f32) -> Self {
- Text { start: self.start.scale(scale), ..self.clone() }
+ Text {
+ start: self.start.scale(scale),
+ ..self.clone()
+ }
}
}
@@ -134,7 +156,6 @@ fn escape_html_text(s: &str) -> String {
s.chars().map(|ch| replace_html_char(ch)).collect()
}
-
impl fmt::Display for Text {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "T {} {}", self.start, self.text)
@@ -143,15 +164,19 @@ impl fmt::Display for Text {
impl Into<Node<()>> for Text {
fn into(self) -> Node<()> {
- svg::tags::text(vec![x(self.start.x), y(self.start.y)], vec![text(escape_html_text(
- &self.text,
- ))])
+ svg::tags::text(
+ vec![x(self.start.x), y(self.start.y)],
+ vec![text(escape_html_text(&self.text))],
+ )
}
}
impl Bounds for Text {
fn bounds(&self) -> (Point, Point) {
- (self.start, Point::new(self.start.x + self.text_width(), self.start.y))
+ (
+ self.start,
+ Point::new(self.start.x + self.text_width(), self.start.y),
+ )
}
}
@@ -160,7 +185,9 @@ impl Eq for Text {}
/// This is needed since this struct contains f32 which rust doesn't provide Eq implementation
impl Ord for Text {
fn cmp(&self, other: &Self) -> Ordering {
- self.start.cmp(&other.start).then(self.text.cmp(&other.text))
+ self.start
+ .cmp(&other.start)
+ .then(self.text.cmp(&other.text))
}
}
@@ -181,6 +208,7 @@ mod tests {
use crate::{
buffer::{Cell, CellBuffer, Contacts, Span},
fragment::CellText,
+ Settings,
};
#[test]
@@ -216,7 +244,7 @@ mod tests {
let mut spans: Vec<Span> = cell_buffer.group_adjacents();
assert_eq!(spans.len(), 1);
let span1 = spans.remove(0);
- let groups = span1.get_contacts();
+ let groups = span1.get_contacts(&Settings::default());
for (i, group) in groups.iter().enumerate() {
println!("group{}\n{}", i, group);
}
@@ -257,8 +285,9 @@ mod tests {
let cell_buffer = CellBuffer::from(art);
let mut spans: Vec<Span> = cell_buffer.group_adjacents();
assert_eq!(spans.len(), 2);
- let groups2 = spans.remove(1).get_contacts();
- let groups1 = spans.remove(0).get_contacts();
+ let settings = &Settings::default();
+ let groups2 = spans.remove(1).get_contacts(settings);
+ let groups1 = spans.remove(0).get_contacts(settings);
println!("span1 groups:");
for (i, group1) in groups1.iter().enumerate() {
println!("\tgroup {} {}", i, group1);
@@ -269,7 +298,13 @@ mod tests {
}
assert_eq!(groups1.len(), 15);
assert_eq!(groups2.len(), 33);
- assert_eq!(groups1[0].as_ref()[0].as_cell_text().unwrap().start, Cell::new(0, 0));
- assert_eq!(groups2[0].as_ref()[0].as_cell_text().unwrap().start, Cell::new(0, 0));
+ assert_eq!(
+ groups1[0].as_ref()[0].as_cell_text().unwrap().start,
+ Cell::new(0, 0)
+ );
+ assert_eq!(
+ groups2[0].as_ref()[0].as_cell_text().unwrap().start,
+ Cell::new(0, 0)
+ );
}
}
diff --git a/svgbob/src/buffer/property_buffer.rs b/svgbob/src/buffer/property_buffer.rs
index b515e15..4642273 100644
--- a/svgbob/src/buffer/property_buffer.rs
+++ b/svgbob/src/buffer/property_buffer.rs
@@ -1,7 +1,7 @@
use crate::{
fragment,
map::{ASCII_PROPERTIES, UNICODE_FRAGMENTS},
- Cell, Fragment, FragmentBuffer,
+ Cell, Fragment, FragmentBuffer, Settings,
};
pub use property::{Property, Signal};
use std::{
@@ -31,27 +31,33 @@ impl<'p> PropertyBuffer<'p> {
/// into the most fitting ascii / unicode character
pub fn match_char_from_cell(
&self,
+ settings: &Settings,
cell: Cell,
fragments: &Vec<Fragment>,
try_unicode: bool,
) -> Option<char> {
// try the unicode first
- let matched_unicode = if try_unicode { Fragment::match_unicode(fragments) } else { None };
+ let matched_unicode = if try_unicode {
+ Fragment::match_unicode(fragments)
+ } else {
+ None
+ };
if let Some(matched_unicode) = matched_unicode {
Some(matched_unicode)
} else {
let empty = &&Property::empty();
- let top_left = self.get(&cell.top_left()).unwrap_or(empty);
- let top = self.get(&cell.top()).unwrap_or(empty);
- let top_right = self.get(&cell.top_right()).unwrap_or(empty);
- let left = self.get(&cell.left()).unwrap_or(empty);
- let right = self.get(&cell.right()).unwrap_or(empty);
- let bottom_left = self.get(&cell.bottom_left()).unwrap_or(empty);
- let bottom = self.get(&cell.bottom()).unwrap_or(empty);
- let bottom_right = self.get(&cell.bottom_right()).unwrap_or(empty);
+ let top_left = self.as_ref().get(&cell.top_left()).unwrap_or(empty);
+ let top = self.as_ref().get(&cell.top()).unwrap_or(empty);
+ let top_right = self.as_ref().get(&cell.top_right()).unwrap_or(empty);
+ let left = self.as_ref().get(&cell.left()).unwrap_or(empty);
+ let right = self.as_ref().get(&cell.right()).unwrap_or(empty);
+ let bottom_left = self.as_ref().get(&cell.bottom_left()).unwrap_or(empty);
+ let bottom = self.as_ref().get(&cell.bottom()).unwrap_or(empty);
+ let bottom_right = self.as_ref().get(&cell.bottom_right()).unwrap_or(empty);
Self::match_char_with_surrounding_properties(
+ settings,
&fragments,
top_left,
top,
@@ -68,6 +74,7 @@ impl<'p> PropertyBuffer<'p> {
/// if the fragments match to the return fragments
/// of the property behavior, then it is a match
pub fn match_char_with_surrounding_properties(
+ settings: &Settings,
fragments: &Vec<Fragment>,
top_left: &Property,
top: &Property,
@@ -91,6 +98,7 @@ impl<'p> PropertyBuffer<'p> {
} else {
ASCII_PROPERTIES.iter().find_map(|(ch, property)| {
let mut behavioral_fragments = property.fragments(
+ settings,
top_left,
top,
top_right,
@@ -117,34 +125,33 @@ impl<'p> PropertyBuffer<'p> {
}
}
-impl<'p> Deref for PropertyBuffer<'p> {
- type Target = HashMap<Cell, &'p Property>;
-
- fn deref(&self) -> &Self::Target {
+impl<'p> AsRef<HashMap<Cell, &'p Property>> for PropertyBuffer<'p> {
+ fn as_ref(&self) -> &HashMap<Cell, &'p Property> {
&self.0
}
}
-impl<'p> DerefMut for PropertyBuffer<'p> {
- fn deref_mut(&mut self) -> &mut Self::Target {
+impl<'p> AsMut<HashMap<Cell, &'p Property>> for PropertyBuffer<'p> {
+ fn as_mut(&mut self) -> &mut HashMap<Cell, &'p Property> {
&mut self.0
}
}
/// convert property buffer to fragment buffer
-impl<'p> Into<FragmentBuffer> for &PropertyBuffer<'p> {
- fn into(self) -> FragmentBuffer {
+impl<'p> PropertyBuffer<'p> {
+ pub(crate) fn into_fragment_buffer(&self, settings: &Settings) -> FragmentBuffer {
let mut fb = FragmentBuffer::new();
- for (cell, property) in self.deref() {
+ for (cell, property) in self.as_ref() {
let empty = &&Property::empty();
- let top_left = self.get(&cell.top_left()).unwrap_or(empty);
- let top = self.get(&cell.top()).unwrap_or(empty);
- let top_right = self.get(&cell.top_right()).unwrap_or(empty);
- let left = self.get(&cell.left()).unwrap_or(empty);
- let right = self.get(&cell.right()).unwrap_or(empty);
- let bottom_left = self.get(&cell.bottom_left()).unwrap_or(empty);
- let bottom = self.get(&cell.bottom()).unwrap_or(empty);
- let bottom_right = self.get(&cell.bottom_right()).unwrap_or(empty);
+ let top_left = self.as_ref().get(&cell.top_left()).unwrap_or(empty);
+ let top = self.as_ref().get(&cell.top()).unwrap_or(empty);
+ let top_right = self.as_ref().get(&cell.top_right()).unwrap_or(empty);
+ let left = self.as_ref().get(&cell.left()).unwrap_or(empty);
+ let right = self.as_ref().get(&cell.right()).unwrap_or(empty);
+ let bottom_left = self.as_ref().get(&cell.bottom_left()).unwrap_or(empty);
+ let bottom = self.as_ref().get(&cell.bottom()).unwrap_or(empty);
+ let bottom_right = self.as_ref().get(&cell.bottom_right()).unwrap_or(empty);
let cell_fragments = property.fragments(
+ settings,
top_left,
top,
top_right,
@@ -194,6 +201,7 @@ mod tests {
let bottom = &Property::empty();
let bottom_right = &Property::empty();
let ch = PropertyBuffer::match_char_with_surrounding_properties(
+ &Settings::default(),
&fragments,
top_left,
top,
@@ -230,6 +238,7 @@ mod tests {
let bottom = &Property::empty();
let bottom_right = &Property::empty();
let ch = PropertyBuffer::match_char_with_surrounding_properties(
+ &Settings::default(),
&fragments,
top_left,
top,
@@ -267,6 +276,7 @@ mod tests {
let bottom = &Property::from_char('|').unwrap();
let bottom_right = &Property::empty();
let ch = PropertyBuffer::match_char_with_surrounding_properties(
+ &Settings::default(),
&fragments,
top_left,
top,
@@ -299,6 +309,7 @@ mod tests {
let bottom = &Property::empty();
let bottom_right = &Property::empty();
let ch = PropertyBuffer::match_char_with_surrounding_properties(
+ &Settings::default(),
&fragments,
top_left,
top,
@@ -331,6 +342,7 @@ mod tests {
let bottom = &Property::empty();
let bottom_right = &Property::empty();
let ch = PropertyBuffer::match_char_with_surrounding_properties(
+ &Settings::default(),
&fragments,
top_left,
top,
diff --git a/svgbob/src/buffer/property_buffer/property.rs b/svgbob/src/buffer/property_buffer/property.rs
index 19c1939..0e5066d 100644
--- a/svgbob/src/buffer/property_buffer/property.rs
+++ b/svgbob/src/buffer/property_buffer/property.rs
@@ -1,7 +1,7 @@
use self::Signal::Strong;
use crate::{
map::{ASCII_PROPERTIES, UNICODE_PROPERTIES},
- Fragment, Point,
+ Fragment, Point, Settings,
};
use std::{cmp, fmt, sync::Arc};
@@ -58,6 +58,7 @@ pub struct Property {
/// depending on flag that is meet when checked agains the surrounding characters
pub behavior: Arc<
dyn Fn(
+ &Settings,
&Property,
&Property,
&Property,
@@ -74,7 +75,12 @@ pub struct Property {
impl fmt::Debug for Property {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- writeln!(f, "{{ char: {}, has {} signature }}", self.ch, self.signature.len())
+ writeln!(
+ f,
+ "{{ char: {}, has {} signature }}",
+ self.ch,
+ self.signature.len()
+ )
}
}
@@ -84,6 +90,7 @@ impl Property {
signature: Vec<(Signal, Vec<Fragment>)>,
behavior: Arc<
dyn Fn(
+ &Settings,
&Property,
&Property,
&Property,
@@ -97,7 +104,11 @@ impl Property {
+ Send,
>,
) -> Self {
- Property { ch, signature, behavior }
+ Property {
+ ch,
+ signature,
+ behavior,
+ }
}
/// get the matching property of this char
@@ -113,7 +124,11 @@ impl Property {
/// empty property serves as a substitue for None property for simplicity in
/// the behavior code, never have to deal with Option
pub fn empty() -> Self {
- Property { ch: ' ', signature: vec![], behavior: Arc::new(|_, _, _, _, _, _, _, _| vec![]) }
+ Property {
+ ch: ' ',
+ signature: vec![],
+ behavior: Arc::new(|_, _, _, _, _, _, _, _, _| vec![]),
+ }
}
/// derive a strong property with a strong signal
@@ -122,7 +137,7 @@ impl Property {
ch,
signature: vec![(Signal::Strong, fragments)],
//TODO find a way to move the fragments here
- behavior: Arc::new(|_, _, _, _, _, _, _, _| vec![(true, vec![])]),
+ behavior: Arc::new(|_, _, _, _, _, _, _, _, _| vec![(true, vec![])]),
}
}
@@ -130,7 +145,13 @@ impl Property {
let mut fragments: Vec<Fragment> = self
.signature
.iter()
- .filter_map(|(sig, fragments)| if *sig == signal { Some(fragments) } else { None })
+ .filter_map(|(sig, fragments)| {
+ if *sig == signal {
+ Some(fragments)
+ } else {
+ None
+ }
+ })
.flatten()
.map(Clone::clone)
.collect();
@@ -183,9 +204,12 @@ impl Property {
/// Check to see if any fragment that is generated in this character
/// can overlap (completely covered) line a b
fn line_overlap_with_signal(&self, a: Point, b: Point, required_signal: Signal) -> bool {
- self.signature.iter().filter(|(signal, _signature)| *signal >= required_signal).any(
- |(_signal, signature)| signature.iter().any(|fragment| fragment.line_overlap(a, b)),
- )
+ self.signature
+ .iter()
+ .filter(|(signal, _signature)| *signal >= required_signal)
+ .any(|(_signal, signature)| {
+ signature.iter().any(|fragment| fragment.line_overlap(a, b))
+ })
}
/// Check to see if any fragment that is generated in this character
@@ -199,6 +223,7 @@ impl Property {
/// the fragments of this property when the surrounding properties is supplied
pub(in crate) fn fragments(
&self,
+ settings: &Settings,
top_left: &Property,
top: &Property,
top_right: &Property,
@@ -209,6 +234,7 @@ impl Property {
bottom_right: &Property,
) -> Vec<Fragment> {
let bool_fragments = self.behavior.as_ref()(
+ settings,
top_left,
top,
top_right,
@@ -219,12 +245,14 @@ impl Property {
bottom_right,
);
let cell_fragments: Vec<Fragment> =
- bool_fragments.into_iter().fold(vec![], |mut acc, (passed, fragments)| {
- if passed {
- acc.extend(fragments);
- };
- acc
- });
+ bool_fragments
+ .into_iter()
+ .fold(vec![], |mut acc, (passed, fragments)| {
+ if passed {
+ acc.extend(fragments);
+ };
+ acc
+ });
cell_fragments
}
}
diff --git a/svgbob/src/map/ascii_map.rs b/svgbob/src/map/ascii_map.rs
index 6576ce4..fad9d56 100644
--- a/svgbob/src/map/ascii_map.rs
+++ b/svgbob/src/map/ascii_map.rs
@@ -4,7 +4,7 @@ use crate::{
ArrowBottom, ArrowBottomLeft, ArrowBottomRight, ArrowLeft, ArrowRight, ArrowTop,
ArrowTopLeft, ArrowTopRight, DiamondBullet,
},
- Cell, CellGrid,
+ Cell, CellGrid, Settings,
},
fragment::{arc, broken_line, circle, line, polygon, rect},
Fragment, Property,
@@ -98,7 +98,7 @@ lazy_static! {
let map: Vec<(
char,
Vec<(Signal, Vec<Fragment>)>,
- Arc<dyn Fn(&Property, &Property, &Property, &Property, &Property, &Property, &Property, &Property) -> Vec<(bool, Vec<Fragment>)> + Sync + Send >,
+ Arc<dyn Fn(&Settings, &Property, &Property, &Property, &Property, &Property, &Property, &Property, &Property) -> Vec<(bool, Vec<Fragment>)> + Sync + Send >,
)> = vec![
///////////////
// dash -
@@ -109,7 +109,7 @@ lazy_static! {
(Strong, vec![line(k, o)]),
],
Arc::new(
- move|top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
+ move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
vec![
(true, vec![line(k, o)]),
]
@@ -125,7 +125,7 @@ lazy_static! {
(Strong, vec![broken_line(k, o)]),
],
Arc::new(
- move|top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
+ move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
vec![
(true, vec![broken_line(k, o)]),
]
@@ -141,7 +141,7 @@ lazy_static! {
(Strong, vec![line(c,w)]),
],
Arc::new(
- move|top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
+ move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
vec![
(!bottom_left.is('/') && !bottom_right.is('\\') && !top_left.is('\\') && !top_right.is('/'), vec![line(c,w)]),
// _
@@ -180,7 +180,7 @@ lazy_static! {
(Strong, vec![broken_line(c,w)]),
],
Arc::new(
- move|top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
+ move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
vec![
(top.line_strongly_overlap(r,w) || bottom.line_strongly_overlap(c,h), vec![broken_line(c,w)]),
]
@@ -196,7 +196,7 @@ lazy_static! {
(Strong, vec![broken_line(c,w)]),
],
Arc::new(
- move|top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
+ move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
vec![
(top.line_strongly_overlap(r,w) || bottom.line_strongly_overlap(c,h), vec![broken_line(c,w)]),
]
@@ -213,7 +213,7 @@ lazy_static! {
(Weak, vec![line(a,y), line(u,e)]),
],
Arc::new(
- move|top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
+ move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
vec![
// |
// +
@@ -256,7 +256,7 @@ lazy_static! {
(Strong, vec![line(a,y), line(u,e)]),
],
Arc::new(
- move|top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
+ move|settings, top_left, top, top_right, left, right, bottom_left, bottom, bottom_right| {
vec![
// \ X