Path Bool library code cleanup (#2000)

* Remove log statements

* Add feature gates to functions in path.rs

* Fix infinite parsing loop and add new test

* License tweaks

* Remove trailing zero in whole number floats

* Flatten visual-tests directory

* Code review

* Clean up printlines

* Add error handling to path parsing

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Dennis Kobert 2024-09-23 12:16:31 +02:00 committed by GitHub
parent 3ddc052538
commit 8a1089938e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
175 changed files with 442 additions and 346 deletions

View file

@ -1,3 +1,6 @@
use crate::path_boolean::{self, FillRule, PathBooleanOperation};
use crate::path_data::{path_from_path_data, path_to_path_data};
use core::panic;
use glob::glob;
use image::{DynamicImage, GenericImageView, RgbaImage};
@ -8,9 +11,6 @@ use std::fs;
use std::path::PathBuf;
use svg::parser::Event;
use crate::path_boolean::{self, FillRule, PathBooleanOperation};
use crate::path_data::{path_from_path_data, path_to_path_data};
const TOLERANCE: u8 = 84;
fn get_fill_rule(fill_rule: &str) -> FillRule {
@ -31,7 +31,7 @@ fn visual_tests() {
("fracture", PathBooleanOperation::Fracture),
];
let folders: Vec<(String, PathBuf, &str, PathBooleanOperation)> = glob("__fixtures__/visual-tests/*/")
let folders: Vec<(String, PathBuf, &str, PathBooleanOperation)> = glob("visual-tests/*/")
.expect("Failed to read glob pattern")
.flat_map(|entry| {
let dir = entry.expect("Failed to get directory entry");
@ -58,6 +58,7 @@ fn visual_tests() {
let mut width = String::new();
let mut height = String::new();
let mut view_box = String::new();
let mut transform = String::new();
for event in svg_tree {
match event {
Event::Tag("svg", svg::node::element::tag::Type::Start, attributes) => {
@ -65,6 +66,11 @@ fn visual_tests() {
height = attributes.get("height").map(|s| s.to_string()).unwrap_or_default();
view_box = attributes.get("viewBox").map(|s| s.to_string()).unwrap_or_default();
}
Event::Tag("g", svg::node::element::tag::Type::Start, attributes) => {
if let Some(transform_attr) = attributes.get("transform") {
transform = transform_attr.to_string();
}
}
Event::Tag("path", svg::node::element::tag::Type::Empty, attributes) => {
let data = attributes.get("d").map(|s| s.to_string()).expect("Path data not found");
let fill_rule = attributes.get("fill-rule").map(|v| v.to_string()).unwrap_or_else(|| "nonzero".to_string());
@ -98,19 +104,25 @@ fn visual_tests() {
let a_node = paths[0].clone();
let b_node = paths[1].clone();
let a = path_from_path_data(&a_node.0);
let b = path_from_path_data(&b_node.0);
let a = path_from_path_data(&a_node.0).unwrap();
let b = path_from_path_data(&b_node.0).unwrap();
let a_fill_rule = get_fill_rule(&a_node.1);
let b_fill_rule = get_fill_rule(&b_node.1);
let result = path_boolean::path_boolean(&a, a_fill_rule, &b, b_fill_rule, op).unwrap();
// Create the result SVG with correct dimensions
// Create the result SVG with correct dimensions and transform
let mut result_svg = format!("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"{}\" height=\"{}\" viewBox=\"{}\">", width, height, view_box);
if !transform.is_empty() {
result_svg.push_str(&format!("<g transform=\"{}\">", transform));
}
for path in &result {
result_svg.push_str(&format!("<path d=\"{}\" {}/>", path_to_path_data(path, 1e-4), first_path_attributes));
}
if !transform.is_empty() {
result_svg.push_str("</g>");
}
result_svg.push_str("</svg>");
// Save the result SVG