aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2024-06-26 11:16:24 +0200
committerjaseg <git@jaseg.de>2024-06-26 11:16:24 +0200
commit6f075fff2b597125af243972baf60e254d78c28a (patch)
treecb1a8620f4e461a7b7420430af8b1aad2b3a6fd7
parent419fa73865d0c90b615874e41ac84dff9e17d7b7 (diff)
downloadgerbolyze-6f075fff2b597125af243972baf60e254d78c28a.tar.gz
gerbolyze-6f075fff2b597125af243972baf60e254d78c28a.tar.bz2
gerbolyze-6f075fff2b597125af243972baf60e254d78c28a.zip
svg-flatten: Fix handling of missing viewBox
This makes svg-flatten compatible with usvg v0.42.0, which changed its viewbox/width/height output. Closes #47
-rw-r--r--svg-flatten/src/svg_doc.cpp30
1 files changed, 27 insertions, 3 deletions
diff --git a/svg-flatten/src/svg_doc.cpp b/svg-flatten/src/svg_doc.cpp
index 163402e..66ead95 100644
--- a/svg-flatten/src/svg_doc.cpp
+++ b/svg-flatten/src/svg_doc.cpp
@@ -54,12 +54,33 @@ bool gerbolyze::SVGDocument::load(istream &in, double scale) {
return false;
}
+ page_w = usvg_double_attr(root_elem, "width", std::nan(""));
+ page_h = usvg_double_attr(root_elem, "height", std::nan(""));
+
/* Set up the document's viewport transform */
istringstream vb_stream(root_elem.attribute("viewBox").value());
vb_stream >> vb_x >> vb_y >> vb_w >> vb_h;
+ if (vb_stream.eof() || vb_stream.fail()) {
+ if (root_elem.attribute("viewBox")) { /* A document with just width/height and no viewBox is okay. */
+ cerr << "Warning: Invalid viewBox, defaulting to width/height values" << endl;
+ }
+
+ if (isnan(page_w) || isnan(page_h)) {
+ cerr << "Warning: Neither width/height nor viewBox given on <svg> root element. Guessing document scale and size." << endl;
+ vb_w = vb_h = page_w = page_h = 200000 / 25.4 * assumed_usvg_dpi / scale;
+ vb_x = vb_y = -vb_w/2;
+ } else {
+ cerr << "No viewBox given on <svg> root, using width/height attributes." << endl;
+ vb_x = vb_y = 0;
+ vb_w = page_w;
+ vb_h = page_h;
+ }
+ } else if (isnan(page_w) || isnan(page_h)) {
+ cerr << "No page width or height given, defaulting to viewBox values units." << endl;
+ page_w = vb_w;
+ page_h = vb_h;
+ }
- page_w = usvg_double_attr(root_elem, "width");
- page_h = usvg_double_attr(root_elem, "height");
/* usvg resolves all units, but instead of outputting some reasonable absolute length like mm, it converts
* everything to px, which depends on usvg's DPI setting (--dpi).
*/
@@ -73,6 +94,9 @@ bool gerbolyze::SVGDocument::load(istream &in, double scale) {
cerr << "Warning: Document has different document unit scale in x and y direction! Output will likely be garbage!" << endl;
}
+ cerr << "Resulting page width " << page_w_mm << " mm x " << page_h_mm << " mm" << endl;
+ cerr << "Resulting document scale " << fabs(vb_w/page_w) << " x " << fabs(vb_h/page_h) << endl;
+
/* Get the one document defs element */
defs_node = root_elem.child("defs");
if (!defs_node) {
@@ -304,7 +328,7 @@ void gerbolyze::SVGDocument::export_svg_path(RenderContext &ctx, const pugi::xml
//double ngon_area_relative = p.size()/(2*std::numbers::pi) * sin(2*std::numbers::pi / p.size());
// ^- correction not necessary, we already do a very good job.
double diameter = sqrt(4*fabs(area)/std::numbers::pi) / clipper_scale;
- double tolerance = ctx.settings().geometric_tolerance_mm;
+ double tolerance = mm_to_doc_units(ctx.settings().geometric_tolerance_mm);
diameter = round(diameter/tolerance) * tolerance;
ctx.sink() << ApertureToken(diameter) << FlashToken(centroid);
}