aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjaseg <git-bigdata-wsl-arch@jaseg.de>2021-02-17 18:58:11 +0100
committerjaseg <git-bigdata-wsl-arch@jaseg.de>2021-02-17 18:58:11 +0100
commitda9d7280d5d099c65f3e8d134a60b4778a5bcfb2 (patch)
tree935676348176d3a06032ff4ac4440081a59a17bd
parentf9c5c00f513e6c6be70b033782976fd109eb4ac9 (diff)
downloadgerbolyze-da9d7280d5d099c65f3e8d134a60b4778a5bcfb2.tar.gz
gerbolyze-da9d7280d5d099c65f3e8d134a60b4778a5bcfb2.tar.bz2
gerbolyze-da9d7280d5d099c65f3e8d134a60b4778a5bcfb2.zip
svg-flatten: add curve flattening tolerance command line param
-rw-r--r--svg-flatten/include/gerbolyze.hpp3
-rw-r--r--svg-flatten/src/main.cpp10
-rw-r--r--svg-flatten/src/svg_doc.cpp13
-rw-r--r--svg-flatten/src/svg_path.cpp4
-rw-r--r--svg-flatten/src/svg_path.h2
5 files changed, 19 insertions, 13 deletions
diff --git a/svg-flatten/include/gerbolyze.hpp b/svg-flatten/include/gerbolyze.hpp
index 96a4103..dc06c89 100644
--- a/svg-flatten/include/gerbolyze.hpp
+++ b/svg-flatten/include/gerbolyze.hpp
@@ -139,6 +139,7 @@ namespace gerbolyze {
class RenderSettings {
public:
double m_minimum_feature_size_mm = 0.1;
+ double curve_tolerance_mm;
VectorizerSelectorizer &m_vec_sel;
};
@@ -174,7 +175,7 @@ namespace gerbolyze {
void export_svg_path(const RenderSettings &rset, const pugi::xml_node &node, ClipperLib::Paths &clip_path);
void setup_debug_output(std::string filename="");
void setup_viewport_clip();
- void load_clips();
+ void load_clips(const RenderSettings &rset);
void load_patterns();
bool _valid;
diff --git a/svg-flatten/src/main.cpp b/svg-flatten/src/main.cpp
index 3427373..0abe3d1 100644
--- a/svg-flatten/src/main.cpp
+++ b/svg-flatten/src/main.cpp
@@ -42,6 +42,9 @@ int main(int argc, char **argv) {
{"min_feature_size", {"-d", "--trace-space"},
"Minimum feature size of elements in vectorized graphics (trace/space) in mm. Default: 0.1mm.",
1},
+ {"curve_tolerance", {"-c", "--curve-tolerance"},
+ "Tolerance for curve flattening in mm. Default: 0.1mm.",
+ 1},
{"no_header", {"--no-header"},
"Do not export output format header/footer, only export the primitives themselves",
0},
@@ -243,10 +246,8 @@ int main(int argc, char **argv) {
}
delete vec;
- double min_feature_size = 0.1; /* mm */
- if (args["min_feature_size"]) {
- min_feature_size = args["min_feature_size"].as<double>();
- }
+ double min_feature_size = args["min_feature_size"].as<double>(0.1); /* mm */
+ double curve_tolerance = args["curve_tolerance"].as<double>(0.1); /* mm */
string ending = "";
auto idx = in_f_name.rfind(".");
@@ -411,6 +412,7 @@ int main(int argc, char **argv) {
VectorizerSelectorizer vec_sel(vectorizer, args["vectorizer_map"] ? args["vectorizer_map"].as<string>() : "");
RenderSettings rset {
min_feature_size,
+ curve_tolerance,
vec_sel,
};
diff --git a/svg-flatten/src/svg_doc.cpp b/svg-flatten/src/svg_doc.cpp
index f387bcc..00c4bd6 100644
--- a/svg-flatten/src/svg_doc.cpp
+++ b/svg-flatten/src/svg_doc.cpp
@@ -86,7 +86,6 @@ bool gerbolyze::SVGDocument::load(istream &in, string debug_out_filename) {
setup_debug_output(debug_out_filename);
setup_viewport_clip();
- load_clips();
load_patterns();
_valid = true;
@@ -142,10 +141,14 @@ bool IDElementSelector::match(const pugi::xml_node &node, bool included, bool is
/* Recursively export all SVG elements in the given group. */
void gerbolyze::SVGDocument::export_svg_group(const RenderSettings &rset, const pugi::xml_node &group, Paths &parent_clip_path, const ElementSelector *sel, bool included, bool is_root) {
+
+ /* Load clip paths from defs given bezier flattening tolerance from rset */
+ load_clips(rset);
+
/* Enter the group's coordinate system */
cairo_save(cr);
apply_cairo_transform_from_svg(cr, group.attribute("transform").value());
-
+
/* Fetch clip path from global registry and transform it into document coordinates. */
Paths clip_path;
auto *lookup = lookup_clip_path(group);
@@ -237,7 +240,7 @@ void gerbolyze::SVGDocument::export_svg_path(const RenderSettings &rset, const p
PolyTree ptree_stroke;
PolyTree ptree_fill;
PolyTree ptree;
- load_svg_path(cr, node, ptree_stroke, ptree_fill);
+ load_svg_path(cr, node, ptree_stroke, ptree_fill, rset.curve_tolerance_mm);
double _y = 0;
cairo_user_to_device_distance(cr, &stroke_width, &_y);
@@ -462,7 +465,7 @@ void gerbolyze::SVGDocument::load_patterns() {
}
}
-void gerbolyze::SVGDocument::load_clips() {
+void gerbolyze::SVGDocument::load_clips(const RenderSettings &rset) {
/* Set up document-wide clip path registry: Extract clip path definitions from <defs> element */
for (const auto &node : defs_node.children("clipPath")) {
cairo_save(cr);
@@ -481,7 +484,7 @@ void gerbolyze::SVGDocument::load_clips() {
cairo_save(cr);
/* TODO: we currently only support clipPathUnits="userSpaceOnUse", not "objectBoundingBox". */
apply_cairo_transform_from_svg(cr, child.attribute("transform").value());
- load_svg_path(cr, child, ptree_stroke, ptree_fill);
+ load_svg_path(cr, child, ptree_stroke, ptree_fill, rset.curve_tolerance_mm);
cairo_restore (cr);
Paths paths;
diff --git a/svg-flatten/src/svg_path.cpp b/svg-flatten/src/svg_path.cpp
index 68003ad..ce2775d 100644
--- a/svg-flatten/src/svg_path.cpp
+++ b/svg-flatten/src/svg_path.cpp
@@ -110,14 +110,14 @@ static pair<bool, bool> path_to_clipper_via_cairo(cairo_t *cr, ClipperLib::Clipp
return {has_closed, num_subpaths > 1};
}
-void gerbolyze::load_svg_path(cairo_t *cr, const pugi::xml_node &node, ClipperLib::PolyTree &ptree_stroke, ClipperLib::PolyTree &ptree_fill) {
+void gerbolyze::load_svg_path(cairo_t *cr, const pugi::xml_node &node, ClipperLib::PolyTree &ptree_stroke, ClipperLib::PolyTree &ptree_fill, double curve_tolerance) {
auto *path_data = node.attribute("d").value();
auto fill_rule = clipper_fill_rule(node);
/* For open paths, clipper does not correctly remove self-intersections. Thus, we pass everything into
* clipper twice: Once with all paths set to "closed" to compute fill areas, and once with correct
* open/closed properties for stroke offsetting. */
- cairo_set_tolerance (cr, 0.1); /* FIXME make configurable, scale properly for units */
+ cairo_set_tolerance (cr, curve_tolerance); /* FIXME make configurable, scale properly for units */
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
ClipperLib::Clipper c_stroke;
diff --git a/svg-flatten/src/svg_path.h b/svg-flatten/src/svg_path.h
index 689af63..2ab29ec 100644
--- a/svg-flatten/src/svg_path.h
+++ b/svg-flatten/src/svg_path.h
@@ -23,7 +23,7 @@
#include "svg_geom.h"
namespace gerbolyze {
-void load_svg_path(cairo_t *cr, const pugi::xml_node &node, ClipperLib::PolyTree &ptree_stroke, ClipperLib::PolyTree &ptree_fill);
+void load_svg_path(cairo_t *cr, const pugi::xml_node &node, ClipperLib::PolyTree &ptree_stroke, ClipperLib::PolyTree &ptree_fill, double curve_tolerance);
void parse_dasharray(const pugi::xml_node &node, std::vector<double> &out);
void dash_path(const ClipperLib::Path &in, ClipperLib::Paths &out, const std::vector<double> dasharray, double dash_offset=0.0);
}