diff --git a/Cargo.lock b/Cargo.lock index fdd303b..d6bdc5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,63 +1,108 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "bitflags" -version = "1.0.4" +name = "aho-corasick" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "cairo-rs" -version = "0.6.0" +name = "ansi_term" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "glib 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "cairo-sys-rs" -version = "0.8.0" +name = "arrayvec" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "glib" -version = "0.7.1" +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clap" +version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "glib-sys" -version = "0.8.0" +name = "env_logger" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "gobject-sys" -version = "0.8.0" +name = "euclid" +version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "euclid_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "float-cmp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "humantime" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -71,15 +116,241 @@ version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "lsys" +name = "log" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lyon_geom" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "euclid 0.19.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "nodrop" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num-traits" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "numtoa" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "phf" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "phf_shared" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quick-error" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quote" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "roxmltree" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "xmlparser 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "simplecss" version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "siphasher" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "svg2gcode" +version = "0.0.1" +dependencies = [ + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lyon_geom 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", + "svgdom 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "svgdom" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "roxmltree 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "simplecss 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "svgtypes 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "svgtypes" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.15.32" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "pkg-config" -version = "0.3.14" +name = "termcolor" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ucd-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "utf8-ranges" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vec_map" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -96,21 +367,83 @@ name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "wincolor" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xmlparser" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [metadata] +"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e09d8a818b2ccc8983f04d95a9350c3cf8d24cc456cedca3b88fa3a81fdc0e2" -"checksum cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fa13914fdc013387afa771f554f2f71d6ae931f4e5be9246c337d60c3dc484" -"checksum glib 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e8fdc159c196a5dfa53a92929ac4c10c8a6637ffb43951f3fff89c2cd2365" -"checksum glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bda542f3caee39a027638e9644ff89204101ad916fd7370b585ad2c5fc97e61" -"checksum gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23e05a14290d3dc255223cba51db4b0f3da438d5250657996fa99b2a30faf43e" +"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" +"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a" +"checksum euclid 0.19.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7a4719a544a67ed3fc33784c2bd2c6581663dfe83b719a6ae05c6dabc3b51c73" +"checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15" +"checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600" +"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum lyon_geom 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ea0ba5f8d2d91d6d895aca54d1ec0d84ddfa4826f33fbfe8abb39f08f9e4153" +"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" +"checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" +"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +"checksum proc-macro2 0.4.28 (registry+https://github.com/rust-lang/crates.io-index)" = "ba92c84f814b3f9a44c5cfca7d2ad77fa10710867d2bbb1b3d175ab5f47daa12" +"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58" +"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" +"checksum roxmltree 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "53b0200cbfa8b3f6cfd6076592717d697a1ddc57cb2a8fbfd3d133c06011b579" +"checksum simplecss 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "135685097a85a64067df36e28a243e94a94f76d829087ce0be34eeb014260c0e" +"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" +"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum svgdom 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ffe3c59d84b307fc361bbf0baff2aa6f6d7c946fdd4f1fbbcbb7efcd04b0334" +"checksum svgtypes 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06280cc80ac6d6be32d497f068c40a25552cc837519265edab70d9040e64c52b" +"checksum syn 0.15.32 (registry+https://github.com/rust-lang/crates.io-index)" = "846620ec526c1599c070eff393bfeeeb88a93afa2513fc3b49f1fea84cf7b0ed" +"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" +"checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" +"checksum xmlparser 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ecec95f00fb0ff019153e64ea520f87d1409769db3e8f4db3ea588638a3e1cee" diff --git a/Cargo.toml b/Cargo.toml index dd778b0..6790898 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,13 @@ [package] -name = "lsys" -version = "0.1.0" -authors = ["purisame"] +name = "svg2gcode" +version = "0.0.1" +authors = ["Sameer Puri "] edition = "2018" +description = "Convert paths in SVG files to GCode for a pen plotter" [dependencies] -cairo-rs = { version = "^0", features = ["svg"] } +svgdom = "^0" +lyon_geom = "^0" +clap = "^2" +log = "^0" +env_logger = "^0" \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fff0561 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Sameer Puri + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/out/sierpinski.svg b/out/sierpinski.svg index 3ca0101..5573da4 100644 --- a/out/sierpinski.svg +++ b/out/sierpinski.svg @@ -1,6 +1,6 @@ - + diff --git a/src/main.rs b/src/main.rs index 1232fbe..58cabc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,270 +1,453 @@ -extern crate cairo; +#[macro_use] +extern crate clap; +extern crate env_logger; +extern crate svgdom; +#[macro_use] +extern crate log; +extern crate lyon_geom; -use cairo::{svg, Context}; +use std::env; use std::fs::File; -use std::io::Write; +use std::io::{self, Read, Write}; -fn main() { - koch(); - sierpinski(); - arrowhead(); - dragon(); - plant(); - moore(); - hilbert(); - sierpinski_carpet(); - snowflake(); - gosper(); - kolam(); - crystal(); -} +use lyon_geom::math; +use svgdom::{AttributeId, AttributeValue, ElementId, ElementType, FilterSvg, PathSegment}; -fn koch() { - let mut out = File::create("out/koch.svg").unwrap(); - run( - "F", - &['F'], - |c: char| match c { - 'F' => "F+F-F-F+F".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI / 2., - 4, - &mut out, - ); -} +fn main() -> io::Result<()> { + env_logger::init(); + let matches = clap_app!(svg2gcode => + (version: crate_version!()) + (author: crate_authors!()) + (about: crate_description!()) + (@arg FILE: "Selects the input SVG file to use, else reading from stdin") + (@arg tolerance: "Sets the interpolation tolerance for curves") + (@arg feedrate: "Sets the machine feed rate") + ) + .get_matches(); -fn sierpinski() { - let mut out = File::create("out/sierpinski.svg").unwrap(); - run( - "F-G-G", - &['F', 'G'], - |c: char| match c { - 'F' => "F-G+F+G-F".chars().collect(), - 'G' => "GG".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI * 2. / 3., - 4, - &mut out, - ); -} + let input = match matches.value_of("FILE") { + Some(filename) => { + let mut f = File::open(filename)?; + let len = f.metadata()?.len(); + let mut input = String::with_capacity(len as usize + 1); + f.read_to_string(&mut input)?; + input + } + None => { + let mut input = String::new(); + io::stdin().read_to_string(&mut input)?; + input + } + }; -fn arrowhead() { - let mut out = File::create("out/arrowhead.svg").unwrap(); - run( - "A", - &['A', 'B'], - |c: char| match c { - 'A' => "B-A-B".chars().collect(), - 'B' => "A+B+A".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI * 1. / 3., - 6, - &mut out, - ); -} + let tolerance = matches + .value_of("tolerance") + .and_then(|x| x.parse().ok()) + .unwrap_or(0.1); + let feedrate = matches + .value_of("feedrate") + .and_then(|x| x.parse().ok()) + .unwrap_or(3000.0); -fn dragon() { - let mut out = File::create("out/dragon.svg").unwrap(); - run( - "FX", - &['F'], - |c: char| match c { - 'X' => "X+YF+".chars().collect(), - 'Y' => "-FX-Y".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI / 2., - 12, - &mut out, - ); -} + let doc = svgdom::Document::from_str(&input).expect("Invalid or unsupported SVG file"); -fn plant() { - let mut out = File::create("out/plant.svg").unwrap(); - run( - "X", - &['F'], - |c: char| match c { - 'X' => "F-[[X]+X]+F[+FX]-X".chars().collect(), - 'F' => "FF".chars().collect(), - other => vec![other], + let tool_on_action = vec![MachineCode::StopSpindle, MachineCode::Dwell { p: 1.5 }]; + let tool_off_action = vec![ + MachineCode::Dwell { p: 0.1 }, + MachineCode::StartSpindle { + d: Direction::Clockwise, + s: 40.0, }, - std::f64::consts::PI * 25.0 / 180.0, - 5, - &mut out, - ); -} + MachineCode::Dwell { p: 0.2 }, + ]; -fn moore() { - let mut out = File::create("out/moore.svg").unwrap(); - run( - "LFL+F+LFL", - &['F'], - |c: char| match c { - 'L' => "-RF+LFL+FR-".chars().collect(), - 'R' => "+LF-RFR-FL+".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI * 90.0 / 180.0, - 5, - &mut out, - ); -} + let tool = std::cell::Cell::new(Tool::Off); + let tool_on = |p: &mut Program| { + if tool.get() == Tool::Off { + tool_on_action.iter().for_each(|x| { + p.push(x.clone()); + }); + tool.set(Tool::On); + } + }; -fn hilbert() { - let mut out = File::create("out/hilbert.svg").unwrap(); - run( - "A", - &['F'], - |c: char| match c { - 'A' => "-BF+AFA+FB-".chars().collect(), - 'B' => "+AF-BFB-FA+".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI / 2.0, - 6, - &mut out, - ); -} + let tool_off = |p: &mut Program| { + if tool.get() == Tool::On { + tool_off_action.iter().for_each(|x| { + p.push(x.clone()); + }); + tool.set(Tool::Off); + } + }; -fn sierpinski_carpet() { - let mut out = File::create("out/sierpinski_carpet.svg").unwrap(); - run( - "F+F+F+F", - &['F'], - |c: char| match c { - 'F' => "FF+F+F+F+FF".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI / 2., - 4, - &mut out, - ); -} + let is_absolute = std::cell::Cell::from(true); + let incremental = |p: &mut Program| { + if is_absolute.get() { + p.push(MachineCode::IncrementalDistanceMode); + is_absolute.set(false); + } + }; + let absolute = |p: &mut Program| { + if !is_absolute.get() { + p.push(MachineCode::AbsoluteDistanceMode); + is_absolute.set(true); + } + }; -fn snowflake() { - let mut out = File::create("out/snowflake.svg").unwrap(); - run( - "F++F++F", - &['F'], - |c: char| match c { - 'F' => "F-F++F-F".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI / 3., - 4, - &mut out, - ); -} + let mut p = Program::new(); + p.push(MachineCode::UnitsMillimeters); + tool_off(&mut p); + p.push(MachineCode::RapidPositioning { + x: 0.0.into(), + y: 0.0.into(), + }); + tool_on(&mut p); -fn gosper() { - let mut out = File::create("out/gosper.svg").unwrap(); - run( - "XF", - &['F'], - |c: char| match c { - 'X' => "X+YF++YF-FX--FXFX-YF+".chars().collect(), - 'Y' => "-FX+YFYF++YF+FX--FX-Y".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI / 3., - 4, - &mut out, - ); -} + for (id, node) in doc.root().descendants().svg() { + if node.is_graphic() { + match id { + ElementId::Path => { + let attrs = node.attributes(); + if let Some(&AttributeValue::Path(ref path)) = attrs.get_value(AttributeId::D) { + p.push(MachineCode::Named(Box::new(node.id().to_string()))); + let mut cx = 0.0; + let mut cy = 0.0; + for segment in path.iter() { + match segment { + PathSegment::MoveTo { abs, x, y } => { + tool_off(&mut p); + if *abs { + absolute(&mut p); + } else { + incremental(&mut p); + } + p.push(MachineCode::RapidPositioning { + x: (*x).into(), + y: (*y).into(), + }); + if *abs { + cx = *x; + cy = *y; + } else { + cx += *x; + cy += *y; + } + } + PathSegment::ClosePath { abs } => { + tool_off(&mut p); + } + PathSegment::LineTo { abs, x, y } => { + tool_on(&mut p); + if *abs { + absolute(&mut p); + } else { + incremental(&mut p); + } + p.push(MachineCode::LinearInterpolation { + x: (*x).into(), + y: (*y).into(), + z: None, + f: feedrate.into(), + }); + if *abs { + cx = *x; + cy = *y; + } else { + cx += *x; + cy += *y; + } + } + PathSegment::HorizontalLineTo { abs, x } => { + tool_on(&mut p); + if *abs { + absolute(&mut p); + } else { + incremental(&mut p); + } + p.push(MachineCode::LinearInterpolation { + x: (*x).into(), + y: None, + z: None, + f: feedrate.into(), + }); + if *abs { + cx = *x; + } else { + cx += *x; + } + } + PathSegment::VerticalLineTo { abs, y } => { + tool_on(&mut p); + if *abs { + absolute(&mut p); + } else { + incremental(&mut p); + } + p.push(MachineCode::LinearInterpolation { + x: None, + y: (*y).into(), + z: None, + f: feedrate.into(), + }); + if *abs { + cy = *y; + } else { + cy += *y; + } + } + PathSegment::CurveTo { + abs, + x1, + y1, + x2, + y2, + x, + y, + } => { + println!("Curve {:?} starting at ({}, {})", segment, cx, cy); + tool_on(&mut p); + absolute(&mut p); + let from = math::point(cx, cy); + let ctrl1 = if *abs { + math::point(*x1, *y1) + } else { + math::point(cx + *x1, cy + *y1) + }; + let ctrl2 = if *abs { + math::point(*x2, *y2) + } else { + math::point(cx + *x2, cy + *y2) + }; + let to = if *abs { + math::point(*x, *y) + } else { + math::point(cx + *x, cy + *y) + }; + let cbs = lyon_geom::CubicBezierSegment { + from, + ctrl1, + ctrl2, + to, + }; + let last_point = std::cell::Cell::new(math::point(cx, cy)); + cbs.flattened(tolerance).for_each(|point| { + p.push(MachineCode::LinearInterpolation { + x: point.x.into(), + y: point.y.into(), + z: None, + f: feedrate.into(), + }); + last_point.set(point); + }); + cx = last_point.get().x; + cy = last_point.get().y; + } + PathSegment::Quadratic { abs, x1, y1, x, y } => { + tool_on(&mut p); + absolute(&mut p); + let from = math::point(cx, cy); + let ctrl = if *abs { + math::point(*x1, *y1) + } else { + math::point(cx + *x1, cy + *y1) + }; + let to = if *abs { + math::point(*x, *y) + } else { + math::point(cx + *x, cy + *y) + }; + let qbs = lyon_geom::QuadraticBezierSegment { from, ctrl, to }; + let last_point = std::cell::Cell::new(math::point(cx, cy)); + qbs.flattened(tolerance).for_each(|point| { + p.push(MachineCode::LinearInterpolation { + x: point.x.into(), + y: point.y.into(), + z: None, + f: feedrate.into(), + }); + last_point.set(point); + }); + cx = last_point.get().x; + cy = last_point.get().y; + } + PathSegment::EllipticalArc { + abs, + rx, + ry, + x_axis_rotation, + large_arc, + sweep, + x, + y, + } => { + tool_on(&mut p); + absolute(&mut p); + let from = math::point(cx, cy); + let to = if *abs { + math::point(*x, *y) + } else { + math::point(cx + *x, cy + *y) + }; + let sarc = lyon_geom::SvgArc { + from, + to, + radii: math::vector(*rx, *ry), + x_rotation: lyon_geom::euclid::Angle { + radians: *x_axis_rotation, + }, + flags: lyon_geom::ArcFlags { + large_arc: *large_arc, + sweep: *sweep, + }, + }; + let last_point = std::cell::Cell::new(math::point(cx, cy)); + sarc.for_each_flattened( + tolerance, + &mut |point: math::F64Point| { + p.push(MachineCode::LinearInterpolation { + x: point.x.into(), + y: point.y.into(), + z: None, + f: feedrate.into(), + }); + last_point.set(point); + }, + ); + cx = last_point.get().x; + cy = last_point.get().y; + } -fn kolam() { - let mut out = File::create("out/kolam.svg").unwrap(); - run( - "-D--D", - &['F'], - |c: char| match c { - 'A' => "F++FFFF--F--FFFF++F++FFFF--F".chars().collect(), - 'B' => "F--FFFF++F++FFFF--F--FFFF++F".chars().collect(), - 'C' => "BFA--BFA".chars().collect(), - 'D' => "CFC--CFC".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI / 4.0, - 6, - &mut out, - ); -} + _ => panic!("Unsupported path segment type"), + } + } + } + } + _ => { + info!("Other {}", node); + } + } + } + } -fn crystal() { - let mut out = File::create("out/crystal.svg").unwrap(); - run( - "F+F+F+F", - &['F'], - |c: char| match c { - 'F' => "FF+F++F+F".chars().collect(), - other => vec![other], - }, - std::f64::consts::PI / 2., - 4, - &mut out, - ); + tool_off(&mut p); + p.push(MachineCode::RapidPositioning { + x: 0.0.into(), + y: 0.0.into(), + }); + tool_on(&mut p); + p.push(MachineCode::ProgramEnd); + + program2gcode(p, File::create("out.gcode")?) } -fn run( - axiom: &str, - variables_to_draw: &[char], - rules: F, - angle: f64, - iterations: usize, - writer: W, -) where - F: Fn(char) -> Vec + Copy, - W: Write, -{ - let surf = svg::Writer::new(1024.0, 1024.0, writer); - let ctx = Context::new(&surf); - ctx.scale(1024., 1024.); +#[derive(Clone, PartialEq, Eq)] +enum Direction { + Clockwise, + Anticlockwise, +} - ctx.set_line_width(0.001); - ctx.set_source_rgb(0., 0., 0.); +#[derive(Copy, Clone, PartialEq, Eq)] +enum Tool { + Off, + On, +} - let mut state = axiom.to_string(); +macro_rules! write_if_some { + ($w:expr, $s:expr, $v:ident) => { + if let Some(v) = $v { + write!($w, $s, v) + } else { + Ok(()) + } + }; +} - for _ in 0..iterations { - state = state.chars().map(rules).flatten().collect(); - } +#[derive(Clone, PartialEq)] +enum MachineCode { + RapidPositioning { + x: Option, + y: Option, + }, + LinearInterpolation { + x: Option, + y: Option, + z: Option, + f: Option, + }, + Dwell { + p: f64, + }, + UnitsInches, + UnitsMillimeters, + ProgramEnd, + StartSpindle { + d: Direction, + s: f64, + }, + StopSpindle, + AbsoluteDistanceMode, + IncrementalDistanceMode, + Named(Box), +} - // let segment_count = state.chars().filter(|c| variables.contains(&c)).count(); +type Program = Vec; - ctx.move_to(0.5, 0.5); - let mut stack: Vec<((f64, f64), f64)> = vec![]; - let mut curangle = -std::f64::consts::PI / 2.0; - for c in state.chars() { - match c { - '+' => { - // ctx.rotate(angle); - curangle += angle; +fn program2gcode(p: Program, mut w: W) -> io::Result<()> { + use MachineCode::*; + for code in p.iter() { + match code { + RapidPositioning { x, y } => { + if let (None, None) = (x, y) { + continue; + } + write!(w, "G0")?; + write_if_some!(w, " X{}", x)?; + write_if_some!(w, " Y{}", y)?; + writeln!(w)?; + } + LinearInterpolation { x, y, z, f } => { + if let (None, None, None, None) = (x, y, z, f) { + continue; + } + write!(w, "G1")?; + write_if_some!(w, " X{}", x)?; + write_if_some!(w, " Y{}", y)?; + write_if_some!(w, " Z{}", z)?; + write_if_some!(w, " F{}", f)?; + writeln!(w, "")?; } - '-' => { - // ctx.rotate(-angle); - curangle -= angle; + Dwell { p } => { + writeln!(w, "G4 P{}", p)?; } - '|' => { - curangle = -curangle; + UnitsInches => { + writeln!(w, "G20")?; } - '[' => { - stack.push((ctx.get_current_point(), curangle)); + UnitsMillimeters => { + writeln!(w, "G21")?; } - ']' => { - let state = stack.pop().unwrap(); - ctx.move_to((state.0).0, (state.0).1); - curangle = state.1; + ProgramEnd => { + writeln!(w, "M20")?; } - other => { - if variables_to_draw.contains(&other) { - ctx.rel_line_to(0.005 * f64::cos(curangle), 0.005 * f64::sin(curangle)); - } + StartSpindle { d, s } => { + let d = match d { + Direction::Clockwise => 3, + Direction::Anticlockwise => 4, + }; + writeln!(w, "M{} S{}", d, s)?; + } + StopSpindle => { + writeln!(w, "M5")?; + } + AbsoluteDistanceMode => { + writeln!(w, "G90")?; + } + IncrementalDistanceMode => { + writeln!(w, "G91")?; + } + Named(name) => { + writeln!(w, "({})", name)?; } } } - ctx.stroke(); + Ok(()) }