From a68e395cb622b9cb91e408b0846cc10126f8ddad Mon Sep 17 00:00:00 2001
From: jaseg <git@jaseg.de>
Date: Sun, 31 Jan 2021 22:11:34 +0100
Subject: Advanced svg/gerber composition working

---
 svg-flatten/include/gerbolyze.hpp |  3 ++-
 svg-flatten/src/main.cpp          | 18 ++++++++++++++++--
 svg-flatten/src/out_dilater.cpp   |  4 ----
 svg-flatten/src/out_gerber.cpp    | 21 +++++++++++----------
 4 files changed, 29 insertions(+), 17 deletions(-)

(limited to 'svg-flatten')

diff --git a/svg-flatten/include/gerbolyze.hpp b/svg-flatten/include/gerbolyze.hpp
index 1fe13ae..96a4103 100644
--- a/svg-flatten/include/gerbolyze.hpp
+++ b/svg-flatten/include/gerbolyze.hpp
@@ -213,7 +213,7 @@ namespace gerbolyze {
 
     class SimpleGerberOutput : public StreamPolygonSink {
     public:
-        SimpleGerberOutput(std::ostream &out, bool only_polys=false, int digits_int=4, int digits_frac=6, d2p offset={0,0});
+        SimpleGerberOutput(std::ostream &out, bool only_polys=false, int digits_int=4, int digits_frac=6, double scale=1.0, d2p offset={0,0});
         virtual ~SimpleGerberOutput() {}
         virtual SimpleGerberOutput &operator<<(const Polygon &poly);
         virtual SimpleGerberOutput &operator<<(GerberPolarityToken pol);
@@ -227,6 +227,7 @@ namespace gerbolyze {
         double m_height;
         long long int m_gerber_scale;
         d2p m_offset;
+        double m_scale;
     };
 
     class SimpleSVGOutput : public StreamPolygonSink {
diff --git a/svg-flatten/src/main.cpp b/svg-flatten/src/main.cpp
index 135a4c1..d05672a 100644
--- a/svg-flatten/src/main.cpp
+++ b/svg-flatten/src/main.cpp
@@ -82,6 +82,12 @@ int main(int argc, char **argv) {
             {"skip_usvg", {"--no-usvg"},
                 "Do not preprocess input using usvg (do not use unless you know *exactly* what you're doing)",
                 0},
+            {"usvg_dpi", {"--usvg-dpi"},
+                "Passed through to usvg's --dpi, in case the input file has different ideas of DPI than usvg has.",
+                1},
+            {"scale", {"--scale"},
+                "Scale input svg lengths by this factor.",
+                1},
             {"exclude_groups", {"-e", "--exclude-groups"},
                 "Comma-separated list of group IDs to exclude from export. Takes precedence over --only-groups.",
                 1},
@@ -176,7 +182,9 @@ int main(int argc, char **argv) {
         sink = new SimpleSVGOutput(*out_f, only_polys, precision, dark_color, clear_color);
 
     } else if (fmt == "gbr" || fmt == "grb" || fmt == "gerber") {
-        sink = new SimpleGerberOutput(*out_f, only_polys, 4, precision);
+        double scale = args["scale"].as<double>(1.0);
+        cerr << "loading @scale=" << scale << endl;
+        sink = new SimpleGerberOutput(*out_f, only_polys, 4, precision, scale);
 
     } else if (fmt == "s-exp" || fmt == "sexp" || fmt == "kicad") {
         if (!args["sexp_mod_name"]) {
@@ -334,7 +342,13 @@ int main(int argc, char **argv) {
 
     } else {
         cerr << "calling usvg on " << barf << " and " << frob << endl; 
-        const char *command_line[] = {"usvg", "--keep-named-groups", barf.c_str(), frob.c_str(), NULL};
+        int dpi = 96;
+        if (args["usvg_dpi"]) {
+            dpi = args["usvg_dpi"].as<int>();
+        }
+        string dpi_str = to_string(dpi);
+        
+        const char *command_line[] = {"usvg", "--keep-named-groups", "--dpi", dpi_str.c_str(), barf.c_str(), frob.c_str(), NULL};
         struct subprocess_s subprocess;
         int rc = subprocess_create(command_line, subprocess_option_inherit_environment, &subprocess);
         if (rc) {
diff --git a/svg-flatten/src/out_dilater.cpp b/svg-flatten/src/out_dilater.cpp
index c0e5969..1ac1040 100644
--- a/svg-flatten/src/out_dilater.cpp
+++ b/svg-flatten/src/out_dilater.cpp
@@ -52,10 +52,6 @@ Dilater &Dilater::operator<<(GerberPolarityToken pol) {
 }
 
 Dilater &Dilater::operator<<(const Polygon &poly) {
-    static int i = 0;
-    cerr << "dilating poly " << i++ << endl;
-
-    cerr << "got poly of " << poly.size() << " nodes" << endl;
     ClipperLib::Path poly_c;
     for (auto &p : poly) {
         poly_c.push_back({(ClipperLib::cInt)round(p[0] * clipper_scale), (ClipperLib::cInt)round(p[1] * clipper_scale)});
diff --git a/svg-flatten/src/out_gerber.cpp b/svg-flatten/src/out_gerber.cpp
index c320184..b32e6e4 100644
--- a/svg-flatten/src/out_gerber.cpp
+++ b/svg-flatten/src/out_gerber.cpp
@@ -27,11 +27,12 @@
 using namespace gerbolyze;
 using namespace std;
 
-SimpleGerberOutput::SimpleGerberOutput(ostream &out, bool only_polys, int digits_int, int digits_frac, d2p offset)
+SimpleGerberOutput::SimpleGerberOutput(ostream &out, bool only_polys, int digits_int, int digits_frac, double scale, d2p offset)
     : StreamPolygonSink(out, only_polys),
     m_digits_int(digits_int),
     m_digits_frac(digits_frac),
-    m_offset(offset)
+    m_offset(offset),
+    m_scale(scale)
 {
     assert(1 <= digits_int && digits_int <= 9);
     assert(0 <= digits_frac && digits_frac <= 9);
@@ -39,10 +40,10 @@ SimpleGerberOutput::SimpleGerberOutput(ostream &out, bool only_polys, int digits
 }
 
 void SimpleGerberOutput::header_impl(d2p origin, d2p size) {
-    m_offset[0] += origin[0];
-    m_offset[1] += origin[1];
-    m_width = size[0] - origin[0];
-    m_height = size[1] - origin[1];
+    m_offset[0] += origin[0] * m_scale;
+    m_offset[1] += origin[1] * m_scale;
+    m_width = (size[0] - origin[0]) * m_scale;
+    m_height = (size[1] - origin[1]) * m_scale;
     
     if (pow(10, m_digits_int-1) < max(m_width, m_height)) {
         cerr << "Warning: Input has bounding box too large for " << m_digits_int << "." << m_digits_frac << " gerber resolution!" << endl;
@@ -74,16 +75,16 @@ SimpleGerberOutput& SimpleGerberOutput::operator<<(const Polygon &poly) {
     }
 
     /* NOTE: Clipper and gerber both have different fixed-point scales. We get points in double mm. */
-    double x = round((poly[0][0] + m_offset[0]) * m_gerber_scale);
-    double y = round((m_height - poly[0][1] + m_offset[1]) * m_gerber_scale);
+    double x = round((poly[0][0] * m_scale + m_offset[0]) * m_gerber_scale);
+    double y = round((m_height - poly[0][1] * m_scale + m_offset[1]) * m_gerber_scale);
     m_out << "G36*" << endl;
     m_out << "X" << setw(m_digits_int + m_digits_frac) << setfill('0') << (long long int)x
           << "Y" << setw(m_digits_int + m_digits_frac) << setfill('0') << (long long int)y
           << "D02*" << endl;
     m_out << "G01*" << endl;
     for (size_t i=1; i<poly.size(); i++) {
-        double x = round((poly[i][0] + m_offset[0]) * m_gerber_scale);
-        double y = round((m_height - poly[i][1] + m_offset[1]) * m_gerber_scale);
+        double x = round((poly[i][0] * m_scale + m_offset[0]) * m_gerber_scale);
+        double y = round((m_height - poly[i][1] * m_scale + m_offset[1]) * m_gerber_scale);
         m_out << "X" << setw(m_digits_int + m_digits_frac) << setfill('0') << (long long int)x
               << "Y" << setw(m_digits_int + m_digits_frac) << setfill('0') << (long long int)y
               << "D01*" << endl;
-- 
cgit