Skip to content

Commit

Permalink
Remove FLATTENING_TOLERANCE const and add tol parameter down from p…
Browse files Browse the repository at this point in the history
…arse()

- update the ffi wrapper
- tests are using the old const value

Closes #3
  • Loading branch information
naufraghi committed May 3, 2021
1 parent 568562a commit 41aa2cc
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 26 deletions.
4 changes: 2 additions & 2 deletions svg2polylines-ffi/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ typedef struct Polyline {
size_t len;
} Polyline;

uint8_t svg_str_to_polylines(char* svg, Polyline** polylines, size_t* polylines_len);
uint8_t svg_str_to_polylines(char* svg, double tol, Polyline** polylines, size_t* polylines_len);
void free_polylines(Polyline* polylines, size_t polylines_len);


Expand Down Expand Up @@ -53,7 +53,7 @@ int main() {
size_t polylines_len = 0;

// Process data
uint8_t err = svg_str_to_polylines(input, &polylines, &polylines_len);
uint8_t err = svg_str_to_polylines(input, 0.15, &polylines, &polylines_len);

// Error handling
if (err > 0) {
Expand Down
4 changes: 2 additions & 2 deletions svg2polylines-ffi/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
size_t len;
} Polyline;
uint8_t svg_str_to_polylines(char* svg, Polyline** polylines, size_t* polylines_len);
uint8_t svg_str_to_polylines(char* svg, double tol, Polyline** polylines, size_t* polylines_len);
void free_polylines(Polyline* polylines, size_t polylines_len);
''')

Expand Down Expand Up @@ -47,7 +47,7 @@ def print_polyline(p):

polylines = ffi.new('Polyline**')
polylines_len = ffi.new('size_t*')
lib.svg_str_to_polylines(svg_input, polylines, polylines_len)
lib.svg_str_to_polylines(svg_input, 0.15, polylines, polylines_len)


print('Found %d polylines!' % polylines_len[0])
Expand Down
5 changes: 3 additions & 2 deletions svg2polylines-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::ffi::CStr;
use std::mem;

use libc::{c_char, size_t};
use libc::{c_char, c_double, size_t};
use svg2polylines::{parse, CoordinatePair};

/// Structure that contains a pointer to the coordinate pairs as well as the
Expand Down Expand Up @@ -37,6 +37,7 @@ pub struct Polyline {
#[no_mangle]
pub unsafe extern "C" fn svg_str_to_polylines(
svg: *const c_char,
tol: c_double,
polylines: *mut *mut Polyline,
polylines_len: *mut size_t,
) -> u8 {
Expand All @@ -48,7 +49,7 @@ pub unsafe extern "C" fn svg_str_to_polylines(
let r_str = c_str.to_str().unwrap();

// Process
match parse(r_str) {
match parse(r_str, tol) {
Ok(vec) => {
// Convert `Vec<Vec<CoordinatePair>>` to `Vec<Polyline>`
let mut tmp_vec: Vec<Polyline> = vec
Expand Down
2 changes: 1 addition & 1 deletion svg2polylines/examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn main() {
file.read_to_string(&mut s).unwrap();

// Parse data
let polylines: Vec<Polyline> = svg2polylines::parse(&s).unwrap_or_else(|e| {
let polylines: Vec<Polyline> = svg2polylines::parse(&s, 0.15).unwrap_or_else(|e| {
println!("Error: {}", e);
exit(2);
});
Expand Down
2 changes: 1 addition & 1 deletion svg2polylines/examples/preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fn main() {
file.read_to_string(&mut s).unwrap();

// Parse data
let polylines: Vec<Polyline> = svg2polylines::parse(&s).unwrap_or_else(|e| {
let polylines: Vec<Polyline> = svg2polylines::parse(&s, 0.15).unwrap_or_else(|e| {
println!("Error: {}", e);
exit(2);
});
Expand Down
53 changes: 35 additions & 18 deletions svg2polylines/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ use svgtypes::{PathParser, PathSegment};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

const FLATTENING_TOLERANCE: f64 = 0.15;

/// A `CoordinatePair` consists of an x and y coordinate.
#[derive(Debug, PartialEq, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand Down Expand Up @@ -200,7 +198,7 @@ fn parse_xml(svg: &str) -> Result<Vec<String>, String> {
Ok(paths)
}

fn parse_path(expr: &str) -> Result<Vec<Polyline>, String> {
fn parse_path(expr: &str, tol: f64) -> Result<Vec<Polyline>, String> {
trace!("parse_path");
let mut lines = Vec::new();
let mut line = CurrentLine::new();
Expand All @@ -211,7 +209,7 @@ fn parse_path(expr: &str) -> Result<Vec<Polyline>, String> {
let current_segment =
segment.map_err(|e| format!("Could not parse path segment: {}", e))?;
let prev_segment = prev_segment_store.replace(current_segment);
parse_path_segment(&current_segment, prev_segment, &mut line, &mut lines)?;
parse_path_segment(&current_segment, prev_segment, &mut line, tol, &mut lines)?;
}

// Path parsing is done, add previously parsing line if valid
Expand All @@ -226,6 +224,7 @@ fn parse_path(expr: &str) -> Result<Vec<Polyline>, String> {
#[allow(clippy::too_many_arguments)]
fn _handle_cubic_curve(
current_line: &mut CurrentLine,
tol: f64,
abs: bool,
x1: f64,
y1: f64,
Expand All @@ -252,7 +251,7 @@ fn _handle_cubic_curve(
to: Point2D::new(current.x + x, current.y + y),
}
};
for point in curve.flattened(FLATTENING_TOLERANCE) {
for point in curve.flattened(tol) {
current_line.add_absolute(CoordinatePair::new(point.x, point.y));
}
Ok(())
Expand All @@ -263,6 +262,7 @@ fn parse_path_segment(
segment: &PathSegment,
prev_segment: Option<PathSegment>,
current_line: &mut CurrentLine,
tol: f64,
lines: &mut Vec<Polyline>,
) -> Result<(), String> {
trace!("parse_path_segment");
Expand Down Expand Up @@ -308,7 +308,7 @@ fn parse_path_segment(
y,
} => {
trace!("parse_path_segment: CurveTo");
_handle_cubic_curve(current_line, abs, x1, y1, x2, y2, x, y)?;
_handle_cubic_curve(current_line, tol, abs, x1, y1, x2, y2, x, y)?;
}
&PathSegment::SmoothCurveTo { abs, x2, y2, x, y } => {
trace!("parse_path_segment: SmoothCurveTo");
Expand Down Expand Up @@ -344,7 +344,7 @@ fn parse_path_segment(
} else {
(dx, dy)
};
_handle_cubic_curve(current_line, abs, x1, y1, x2, y2, x, y)?;
_handle_cubic_curve(current_line, tol, abs, x1, y1, x2, y2, x, y)?;
}
Some(_) | None => {
// The previous segment was not a curve. Use the current
Expand All @@ -353,7 +353,7 @@ fn parse_path_segment(
Some(pair) => {
let x1 = pair.x;
let y1 = pair.y;
_handle_cubic_curve(current_line, abs, x1, y1, x2, y2, x, y)?;
_handle_cubic_curve(current_line, tol, abs, x1, y1, x2, y2, x, y)?;
}
None => {
return Err(
Expand Down Expand Up @@ -382,7 +382,7 @@ fn parse_path_segment(
to: Point2D::new(current.x + x, current.y + y),
}
};
for point in curve.flattened(FLATTENING_TOLERANCE) {
for point in curve.flattened(tol) {
current_line.add_absolute(CoordinatePair::new(point.x, point.y));
}
}
Expand All @@ -400,7 +400,7 @@ fn parse_path_segment(
}

/// Parse an SVG string into a vector of polylines.
pub fn parse(svg: &str) -> Result<Vec<Polyline>, String> {
pub fn parse(svg: &str, tol: f64) -> Result<Vec<Polyline>, String> {
trace!("parse");

// Parse the XML string into a list of path expressions
Expand All @@ -412,7 +412,7 @@ pub fn parse(svg: &str) -> Result<Vec<Polyline>, String> {

// Process path expressions
for expr in path_exprs {
polylines.extend(parse_path(&expr)?);
polylines.extend(parse_path(&expr, tol)?);
}

trace!("parse: This results in {} polylines", polylines.len());
Expand All @@ -424,6 +424,8 @@ pub fn parse(svg: &str) -> Result<Vec<Polyline>, String> {
mod tests {
use super::*;

const FLATTENING_TOLERANCE: f64 = 0.15;

#[test]
fn test_current_line() {
let mut line = CurrentLine::new();
Expand Down Expand Up @@ -478,6 +480,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -489,6 +492,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -500,6 +504,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -525,20 +530,23 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
parse_path_segment(
&PathSegment::HorizontalLineTo { abs: true, x: 3.0 },
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
parse_path_segment(
&PathSegment::VerticalLineTo { abs: true, y: -1.0 },
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -563,6 +571,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -574,6 +583,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
);
assert!(result.is_err());
Expand All @@ -596,6 +606,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -607,6 +618,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -618,6 +630,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -629,6 +642,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -640,6 +654,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -651,6 +666,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -662,6 +678,7 @@ mod tests {
},
None,
&mut current_line,
FLATTENING_TOLERANCE,
&mut lines,
)
.unwrap();
Expand All @@ -680,7 +697,7 @@ mod tests {
<path d="M 113,35 H 40 L -39,49 H 40" />
</svg>
"#;
let result = parse(&input).unwrap();
let result = parse(&input, FLATTENING_TOLERANCE).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].len(), 4);
assert_eq!(result[0][0], (113., 35.).into());
Expand All @@ -698,7 +715,7 @@ mod tests {
<path d="M 10,10 20,15 10,20 Z" />
</svg>
"#;
let result = parse(&input).unwrap();
let result = parse(&input, FLATTENING_TOLERANCE).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].len(), 4);
assert_eq!(result[0][0], (10., 10.).into());
Expand All @@ -724,7 +741,7 @@ mod tests {
<path d="M 10,10 20,15 10,20 Z m 0,40 H 0" />
</svg>
"#;
let result = parse(&input).unwrap();
let result = parse(&input, FLATTENING_TOLERANCE).unwrap();
assert_eq!(result.len(), 2);

assert_eq!(result[0].len(), 4);
Expand All @@ -747,7 +764,7 @@ mod tests {
<path d="M 10,100 40,70 h 10 m -20,40 10,-20" />
</svg>
"#;
let result = parse(&input).unwrap();
let result = parse(&input, FLATTENING_TOLERANCE).unwrap();

// 2 Polylines
assert_eq!(result.len(), 2);
Expand Down Expand Up @@ -776,7 +793,7 @@ mod tests {
<path d="M 10 20 c 0 0 1 -3 2 -5 s -10 -8 -2 5 z" />
</svg>
"#;
let result = parse(&input).unwrap();
let result = parse(&input, FLATTENING_TOLERANCE).unwrap();
assert_eq!(result.len(), 4);
assert_eq!(result[0], result[1]);
assert_eq!(result[0], result[2]);
Expand Down Expand Up @@ -860,7 +877,7 @@ mod tests {
<path d="m 0.10650371,93.221877 c 0,0 3.74188519,-5.078118 9.62198629,-3.474499 5.880103,1.60362 4.276438,7.216278 4.276438,7.216278"/>
</svg>
"#;
let result = parse(&input).unwrap();
let result = parse(&input, FLATTENING_TOLERANCE).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].len(), 11);
assert_eq!(
Expand Down Expand Up @@ -927,7 +944,7 @@ mod tests {
<path d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"/>
</svg>
"#;
let result = parse(&input).unwrap();
let result = parse(&input, FLATTENING_TOLERANCE).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].len(), 31);
assert_eq!(
Expand Down

0 comments on commit 41aa2cc

Please sign in to comment.