diff --git a/Cargo.lock b/Cargo.lock index fdec8c66..5ad9a257 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,6 +272,14 @@ dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crc32fast" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-deque" version = "0.2.0" @@ -338,14 +346,6 @@ name = "either" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "encoding_rs" -version = "0.8.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "env_logger" version = "0.5.13" @@ -749,6 +749,16 @@ name = "libc" version = "0.2.43" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libflate" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "linked-hash-map" version = "0.4.2" @@ -1075,17 +1085,6 @@ name = "quick-error" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "quick-xml" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "encoding_rs 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "quickcheck" version = "0.7.2" @@ -1159,6 +1158,11 @@ dependencies = [ "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rctree" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "redox_syscall" version = "0.1.40" @@ -1250,6 +1254,14 @@ dependencies = [ "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "roxmltree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "xmlparser 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rsvg" version = "0.3.0" @@ -1377,11 +1389,21 @@ dependencies = [ "pkg-config 0.3.14 (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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "smallvec" version = "0.6.5" @@ -1400,15 +1422,25 @@ name = "strsim" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "svgdom" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "roxmltree 0.4.1 (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.1 (registry+https://github.com/rust-lang/crates.io-index)", + "svgtypes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "svgtypes" -version = "0.2.0" +version = "0.3.0" 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)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", - "xmlparser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1489,11 +1521,11 @@ dependencies = [ "lyon_geom 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "pathfinder_path_utils 0.2.0", - "quick-xml 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "quickcheck 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "svgtypes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "svgtypes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1550,6 +1582,11 @@ name = "unicode-normalization" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-segmentation" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-width" version = "0.1.5" @@ -1583,6 +1620,20 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "usvg" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libflate 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lyon_geom 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rctree 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "svgdom 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "utf8-ranges" version = "1.0.1" @@ -1656,7 +1707,7 @@ dependencies = [ [[package]] name = "xmlparser" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1702,6 +1753,7 @@ source = "git+https://github.com/SergioBenitez/ring?branch=v0.12#9ccfa153a27aecc "checksum core-foundation-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a3fb15cdbdd9cf8b82d97d0296bb5cd3631bba58d6e31650a002a8e7fb5721f9" "checksum core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "62ceafe1622ffc9a332199096841d0ff9912ec8cf8f9cde01e254a7d5217cd10" "checksum core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f46450d6f2397261af420b4ccce23807add2e45fa206410a03d66fb7f050ae" +"checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" @@ -1709,7 +1761,6 @@ source = "git+https://github.com/SergioBenitez/ring?branch=v0.12#9ccfa153a27aecc "checksum dirs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f679c09c1cf5428702cc10f6846c56e4e23420d3a88bcc9335b17c630a7b710b" "checksum dwrote 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "031b304062005e27cc3a7e2be0880e176f468418a89d91a45ba72e82a8a9cfd5" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" -"checksum encoding_rs 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1a8fa54e6689eb2549c4efed8d00d7f3b2b994a064555b0e8df4ae3764bcc4be" "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" "checksum euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70a2ebdf55fb9d6329046e026329a55ef8fbaae5ea833f56e170beb3125a8a5f" "checksum expat-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c470ccb972f2088549b023db8029ed9da9426f5affbf9b62efff7009ab8ed5b1" @@ -1752,6 +1803,7 @@ source = "git+https://github.com/SergioBenitez/ring?branch=v0.12#9ccfa153a27aecc "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum libflate 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "bff3ac7d6f23730d3b533c35ed75eef638167634476a499feef16c428d74b57b" "checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" @@ -1785,7 +1837,6 @@ source = "git+https://github.com/SergioBenitez/ring?branch=v0.12#9ccfa153a27aecc "checksum png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f54b9600d584d3b8a739e1662a595fab051329eff43f20e7d8cc22872962145b" "checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quick-xml 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8065cbb01701c11cc195cde85cbf39d1c6a80705b67a157ebb3042e0e5777f" "checksum quickcheck 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4537d3e4edf73a15dd059b75bed1c292d17d3ea7517f583cebe716794fcf816" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" @@ -1794,6 +1845,7 @@ source = "git+https://github.com/SergioBenitez/ring?branch=v0.12#9ccfa153a27aecc "checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a" "checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa" "checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" +"checksum rctree 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1817e0f0056f95bce0d6ab1a5be62ca24bd756b5547c20637ef47cc9a2065f4b" "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" @@ -1802,6 +1854,7 @@ source = "git+https://github.com/SergioBenitez/ring?branch=v0.12#9ccfa153a27aecc "checksum rocket 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc32be1d093e7b2f9718983318c6bf5a14f43d7ea01a0b5143c3450c90725b9" "checksum rocket_codegen 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc94e7781a8bc502f3614521ae94b562f209c7537671cb6169cbbe9dbcc6c5e" "checksum rocket_contrib 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bae00c367de4599157febc585431c7c647c5f0ffa8fa0e9e875edbbb0bd929" +"checksum roxmltree 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02660467d0c2da1b6276042501aee6e15ec5b8ff59423243f185b294cd53acf3" "checksum rsvg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2032b49fe075a3b921573286f7debe130aebdac6cb37fb197f9b517a4237024" "checksum rsvg-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ceca0b663cfddd09062d7e3fe0a729765d1e61bbbbb6a31d5e23d141ff0db38" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" @@ -1817,11 +1870,14 @@ source = "git+https://github.com/SergioBenitez/ring?branch=v0.12#9ccfa153a27aecc "checksum servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a088f8d775a5c5314aae09bd77340bc9c67d72b9a45258be34c83548b4814cd9" "checksum servo-fontconfig-sys 4.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa080856db55f188aaf36f01cae8c03448a6056552adb77d461179e44e1a14" "checksum servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9232032c2e85118c0282c6562c84cab12316e655491ba0a5d1905b2320060d1b" +"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" "checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" "checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum svgtypes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d7da116a3aedb07023f8399e126d0467bd9629d3a235f339eb7986f779a07c9" +"checksum svgdom 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a9b53b3ed152fc6b871f7232a8772c640567fd25d056941450637ecba32924d" +"checksum svgtypes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c43c25e6de7264024b5e351eb0c342039eb5acf51f2e9d0099bbd324b661453b" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" "checksum syn 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9056ebe7f2d6a38bc63171816fd1d3430da5a43896de21676dc5c0a4b8274a11" "checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" @@ -1837,11 +1893,13 @@ source = "git+https://github.com/SergioBenitez/ring?branch=v0.12#9ccfa153a27aecc "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" +"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "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 unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" "checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" +"checksum usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ebf4d5244ba2e8305caf9de7949377794ecdea5a9e3c84fc5610d78d21f5ee" "checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" @@ -1853,5 +1911,5 @@ source = "git+https://github.com/SergioBenitez/ring?branch=v0.12#9ccfa153a27aecc "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" "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.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ea75f29e9916cc12af3af844a59d2d2ba1ca33aa956e9a162240dc7124cc72bb" +"checksum xmlparser 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d78a7f29bb57edf63321d545d84f99360df71df36929a090bc067e1bcb65e34d" "checksum yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d60c3b48c9cdec42fb06b3b84b5b087405e1fa1c644a1af3930e4dfafe93de48" diff --git a/utils/tile-svg/Cargo.toml b/utils/tile-svg/Cargo.toml index 111a8242..57580b2d 100644 --- a/utils/tile-svg/Cargo.toml +++ b/utils/tile-svg/Cargo.toml @@ -13,9 +13,9 @@ fixedbitset = "0.1" jemallocator = "0.1" lyon_geom = "0.12" lyon_path = "0.12" -quick-xml = "0.12" rayon = "1.0" -svgtypes = "0.2" +svgtypes = "0.3" +usvg = "0.4" [dependencies.pathfinder_path_utils] path = "../../path-utils" diff --git a/utils/tile-svg/src/main.rs b/utils/tile-svg/src/main.rs index 1c3196c6..fb52da3a 100644 --- a/utils/tile-svg/src/main.rs +++ b/utils/tile-svg/src/main.rs @@ -1,6 +1,6 @@ // pathfinder/utils/tile-svg/main.rs // -// Copyright © 2018 The Pathfinder Project Developers. +// Copyright © 2019 The Pathfinder Project Developers. // // Licensed under the Apache License, Version 2.0 or the MIT license @@ -27,22 +27,19 @@ use lyon_geom::{CubicBezierSegment, LineSegment, QuadraticBezierSegment}; use lyon_path::PathEvent; use lyon_path::iterator::PathIter; use pathfinder_path_utils::stroke::{StrokeStyle, StrokeToFillIter}; -use quick_xml::Reader; -use quick_xml::events::{BytesStart, Event}; use rayon::ThreadPoolBuilder; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use std::cmp::Ordering; use std::fmt::{self, Debug, Formatter}; use std::fs::File; -use std::io::{self, BufReader, BufWriter, Write}; +use std::io::{self, BufWriter, Write}; use std::mem; -use std::ops::Range; -use std::path::{Path, PathBuf}; -use std::str::FromStr; +use std::path::PathBuf; use std::time::Instant; use std::u16; -use svgtypes::{Color as SvgColor, PathParser, PathSegment as SvgPathSegment, TransformListParser}; -use svgtypes::{TransformListToken}; +use svgtypes::Color as SvgColor; +use usvg::{Node, NodeExt, NodeKind, Options as UsvgOptions, Paint, PathSegment as UsvgPathSegment}; +use usvg::{Rect as UsvgRect, Transform as UsvgTransform, Tree}; #[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; @@ -89,7 +86,9 @@ fn main() { } thread_pool_builder.build_global().unwrap(); - let scene = Scene::from_path(&input_path); + // Build scene. + let usvg = Tree::from_file(&input_path, &UsvgOptions::default()).unwrap(); + let scene = Scene::from_tree(usvg); println!("Scene bounds: {:?} View box: {:?}", scene.bounds, scene.view_box); //println!("{:#?}", scene.objects[0]); @@ -154,29 +153,7 @@ pub enum PathObjectKind { #[derive(Debug)] struct ComputedStyle { - fill_color: Option, - stroke_width: f32, - stroke_color: Option, - transform: Transform2D, -} - -#[derive(Default)] -struct GroupStyle { - fill_color: Option, - stroke_width: Option, - stroke_color: Option, - transform: Option>, -} - -impl ComputedStyle { - fn new() -> ComputedStyle { - ComputedStyle { - fill_color: None, - stroke_width: 1.0, - stroke_color: None, - transform: Transform2D::identity(), - } - } + color: Option, } #[derive(Clone, Copy, PartialEq, Debug)] @@ -187,17 +164,76 @@ impl Scene { Scene { objects: vec![], styles: vec![], bounds: Rect::zero(), view_box: Rect::zero() } } - fn from_path(path: &Path) -> Scene { - let mut reader = Reader::from_file(&path).unwrap(); - + fn from_tree(tree: Tree) -> Scene { let global_transform = Transform2D::create_scale(SCALE_FACTOR, SCALE_FACTOR); - let mut xml_buffer = vec![]; - let mut group_styles = vec![]; - let mut style = None; - let mut scene = Scene::new(); + let root = &tree.root(); + match *root.borrow() { + NodeKind::Svg(ref svg) => { + scene.view_box = usvg_rect_to_euclid_rect(&svg.view_box.rect); + for kid in root.children() { + process_node(&mut scene, &kid, &global_transform); + } + } + _ => unreachable!(), + }; + + return scene; + + fn process_node(scene: &mut Scene, node: &Node, transform: &Transform2D) { + let node_transform = usvg_transform_to_euclid_transform_2d(&node.transform()); + let transform = transform.pre_mul(&node_transform); + + match *node.borrow() { + NodeKind::Group(_) => { + for kid in node.children() { + process_node(scene, &kid, &transform) + } + } + NodeKind::Path(ref path) => { + if let Some(ref fill) = path.fill { + let style = scene.push_paint(&fill.paint); + + let path = UsvgPathToPathEvents::new(path.segments.iter().cloned()); + let path = PathTransformingIter::new(path, &transform); + let path = MonotonicConversionIter::new(path); + let outline = Outline::from_path_events(path); + + scene.bounds = scene.bounds.union(&outline.bounds); + scene.objects.push(PathObject::new(outline, + style, + node.id().to_string(), + PathObjectKind::Fill)); + } + + if let Some(ref stroke) = path.stroke { + let style = scene.push_paint(&stroke.paint); + let stroke_width = f32::max(stroke.width.value() as f32, + HAIRLINE_STROKE_WIDTH); + + let path = UsvgPathToPathEvents::new(path.segments.iter().cloned()); + let path = PathIter::new(path); + let path = StrokeToFillIter::new(path, StrokeStyle::new(stroke_width)); + let path = PathTransformingIter::new(path, &transform); + let path = MonotonicConversionIter::new(path); + let outline = Outline::from_path_events(path); + + scene.bounds = scene.bounds.union(&outline.bounds); + scene.objects.push(PathObject::new(outline, + style, + node.id().to_string(), + PathObjectKind::Stroke)); + } + } + _ => { + // TODO(pcwalton): Handle these by punting to WebRender. + } + } + } + + /* loop { match reader.read_event(&mut xml_buffer) { Ok(Event::Start(ref event)) | @@ -255,91 +291,18 @@ impl Scene { } return scene; + + */ } - fn push_group_style(&mut self, - reader: &mut Reader>, - event: &BytesStart, - group_styles: &mut Vec, - style: &mut Option) { - let mut group_style = GroupStyle::default(); - let attributes = event.attributes(); - for attribute in attributes { - let attribute = attribute.unwrap(); - match attribute.key { - b"fill" => { - let value = reader.decode(&attribute.value); - if let Ok(color) = SvgColor::from_str(&value) { - group_style.fill_color = Some(color); - } - } - b"stroke" => { - let value = reader.decode(&attribute.value); - if let Ok(color) = SvgColor::from_str(&value) { - group_style.stroke_color = Some(color) - } - } - b"transform" => { - let value = reader.decode(&attribute.value); - let mut current_transform = Transform2D::identity(); - let transform_list_parser = TransformListParser::from(&*value); - for transform in transform_list_parser { - match transform { - Ok(TransformListToken::Matrix { a, b, c, d, e, f }) => { - let transform: Transform2D = - Transform2D::row_major(a, b, c, d, e, f).cast(); - current_transform = current_transform.pre_mul(&transform) - } - Ok(TransformListToken::Scale { sx, sy }) => { - current_transform = - current_transform.pre_scale(sx as f32, sy as f32) - } - _ => { - eprintln!("warning: unknown transform list token"); - } - } - } - group_style.transform = Some(current_transform); - } - b"stroke-width" => { - if let Ok(width) = reader.decode(&attribute.value).parse() { - let width: f32 = width; - //group_style.stroke_width = Some(1.0); - group_style.stroke_width = Some(width); - } - } - _ => {} - } - } - - group_styles.push(group_style); - *style = None; - } - - fn ensure_style(&mut self, current_style: &mut Option, group_styles: &[GroupStyle]) - -> StyleId { - if let Some(current_style) = *current_style { - return current_style - } - - let mut computed_style = ComputedStyle::new(); - for group_style in group_styles { - if let Some(fill_color) = group_style.fill_color { - computed_style.fill_color = Some(fill_color) - } - if let Some(stroke_width) = group_style.stroke_width { - computed_style.stroke_width = stroke_width - } - if let Some(stroke_color) = group_style.stroke_color { - computed_style.stroke_color = Some(stroke_color) - } - if let Some(transform) = group_style.transform { - computed_style.transform = computed_style.transform.pre_mul(&transform) - } - } - + fn push_paint(&mut self, paint: &Paint) -> StyleId { let id = StyleId(self.styles.len() as u32); - self.styles.push(computed_style); + self.styles.push(ComputedStyle { + color: match *paint { + Paint::Color(color) => Some(color), + Paint::Link(..) => None, + } + }); id } @@ -350,15 +313,8 @@ impl Scene { fn build_shader(&self, object_index: u16) -> ObjectShader { let object = &self.objects[object_index as usize]; let style = self.get_style(object.style); - let fill_color = match object.kind { - PathObjectKind::Fill => style.fill_color, - PathObjectKind::Stroke => style.stroke_color, - }; - let fill_color = match fill_color { - None => ColorU::black(), - Some(fill_color) => ColorU::from_svg_color(fill_color), - }; - ObjectShader { fill_color } + let color = style.color.map(ColorU::from_svg_color).unwrap_or(ColorU::black()); + ObjectShader { fill_color: color } } // This function exists to make profiling easier. @@ -384,6 +340,7 @@ impl Scene { }).collect() } + /* fn push_svg_path(&mut self, value: &str, style: StyleId, name: String) { let global_transform = Transform2D::create_scale(SCALE_FACTOR, SCALE_FACTOR); let transform = global_transform.pre_mul(&self.get_style(style).transform); @@ -394,7 +351,7 @@ impl Scene { let path = SvgPathToPathEvents::new(&mut path_parser); let path = PathTransformingIter::new(path, &transform); let path = MonotonicConversionIter::new(path); - let outline = Outline::from_path_events(path, computed_style); + let outline = Outline::from_path_events(path); self.bounds = self.bounds.union(&outline.bounds); self.objects.push(PathObject::new(outline, style, name.clone(), PathObjectKind::Fill)); @@ -410,12 +367,13 @@ impl Scene { let path = StrokeToFillIter::new(path, StrokeStyle::new(stroke_width)); let path = PathTransformingIter::new(path, &transform); let path = MonotonicConversionIter::new(path); - let outline = Outline::from_path_events(path, computed_style); + let outline = Outline::from_path_events(path); self.bounds = self.bounds.union(&outline.bounds); self.objects.push(PathObject::new(outline, style, name, PathObjectKind::Stroke)); } } + */ } impl PathObject { @@ -453,8 +411,7 @@ impl Outline { } // NB: Assumes the path has already been transformed. - fn from_path_events(path_events: I, style: &ComputedStyle) -> Outline - where I: Iterator { + fn from_path_events(path_events: I) -> Outline where I: Iterator { let mut outline = Outline::new(); let mut current_contour = Contour::new(); let mut bounding_points = None; @@ -925,17 +882,6 @@ impl Segment { fn is_none(&self) -> bool { !self.flags.contains(SegmentFlags::HAS_ENDPOINTS) } - - fn min_x(&self) -> f32 { f32::min(self.from.x, self.to.x) } - fn max_x(&self) -> f32 { f32::max(self.from.x, self.to.x) } - - fn winding(&self) -> i32 { - match self.from.x.partial_cmp(&self.to.x) { - Some(Ordering::Less) => -1, - Some(Ordering::Greater) => 1, - Some(Ordering::Equal) | None => 0, - } - } } bitflags! { @@ -1016,8 +962,6 @@ impl<'o> Tiler<'o> { } fn process_old_active_edges(&mut self, tile_y: i16) { - let tile_origin_y = tile_y as f32 * TILE_HEIGHT; - let mut current_tile_x = self.built_object.tile_rect.origin.x; let mut current_subtile_x = 0.0; let mut current_winding = 0; @@ -1431,18 +1375,6 @@ impl BuiltObject { const MAX_U12: f32 = 16.0 - 1.0 / 256.0; - /* - println!("from={:?} to={:?}", from, to); - debug_assert!(from.x > -EPSILON); - debug_assert!(from.x < TILE_WIDTH + EPSILON); - debug_assert!(to.x > -EPSILON); - debug_assert!(to.x < TILE_WIDTH + EPSILON); - debug_assert!(from.y > -EPSILON); - debug_assert!(from.y < TILE_HEIGHT + EPSILON); - debug_assert!(to.y > -EPSILON); - debug_assert!(to.y < TILE_HEIGHT + EPSILON); - */ - let from_px = Point2DU4::new(from.x as u8, from.y as u8); let to_px = Point2DU4::new(to.x as u8, to.y as u8); let from_subpx = Point2D::new((from.x.fract() * 256.0) as u8, @@ -1456,9 +1388,6 @@ impl BuiltObject { }); self.solid_tiles.set(tile_index as usize, false); - - // FIXME(pcwalton): This is really sloppy! - const EPSILON: f32 = 0.25; } fn add_active_fill(&mut self, @@ -1614,107 +1543,45 @@ fn round_rect_out_to_tile_bounds(rect: &Rect) -> Rect { Rect::new(tile_origin, tile_size) } -// SVG stuff +// USVG stuff -struct SvgPathToPathEvents<'a, I> where I: Iterator { - iter: &'a mut I, - last_endpoint: Point2D, - last_ctrl_point: Option>, +fn usvg_rect_to_euclid_rect(rect: &UsvgRect) -> Rect { + Rect::new(Point2D::new(rect.x, rect.y), Size2D::new(rect.width, rect.height)).to_f32() } -impl<'a, I> SvgPathToPathEvents<'a, I> where I: Iterator { - fn new(iter: &'a mut I) -> SvgPathToPathEvents<'a, I> { - SvgPathToPathEvents { iter, last_endpoint: Point2D::zero(), last_ctrl_point: None } +fn usvg_transform_to_euclid_transform_2d(transform: &UsvgTransform) -> Transform2D { + Transform2D::row_major(transform.a as f32, transform.b as f32, + transform.c as f32, transform.d as f32, + transform.e as f32, transform.f as f32) +} + +struct UsvgPathToPathEvents where I: Iterator { + iter: I, +} + +impl UsvgPathToPathEvents where I: Iterator { + fn new(iter: I) -> UsvgPathToPathEvents { + UsvgPathToPathEvents { iter } } } -impl<'a, I> Iterator for SvgPathToPathEvents<'a, I> where I: Iterator { +impl Iterator for UsvgPathToPathEvents where I: Iterator { type Item = PathEvent; fn next(&mut self) -> Option { - return match self.iter.next() { - None => None, - Some(SvgPathSegment::MoveTo { abs, x, y }) => { - let to = compute_point(x, y, abs, &self.last_endpoint); - self.last_endpoint = to; - self.last_ctrl_point = None; - Some(PathEvent::MoveTo(to)) + match self.iter.next()? { + UsvgPathSegment::MoveTo { x, y } => { + Some(PathEvent::MoveTo(Point2D::new(x, y).to_f32())) } - Some(SvgPathSegment::LineTo { abs, x, y }) => { - let to = compute_point(x, y, abs, &self.last_endpoint); - self.last_endpoint = to; - self.last_ctrl_point = None; - Some(PathEvent::LineTo(to)) + UsvgPathSegment::LineTo { x, y } => { + Some(PathEvent::LineTo(Point2D::new(x, y).to_f32())) } - Some(SvgPathSegment::HorizontalLineTo { abs, x }) => { - let to = compute_point(x, 0.0, abs, &self.last_endpoint); - self.last_endpoint = to; - self.last_ctrl_point = None; - Some(PathEvent::LineTo(to)) - } - Some(SvgPathSegment::VerticalLineTo { abs, y }) => { - let to = compute_point(0.0, y, abs, &self.last_endpoint); - self.last_endpoint = to; - self.last_ctrl_point = None; - Some(PathEvent::LineTo(to)) - } - Some(SvgPathSegment::Quadratic { abs, x1, y1, x, y }) => { - let ctrl = compute_point(x1, y1, abs, &self.last_endpoint); - self.last_ctrl_point = Some(ctrl); - let to = compute_point(x, y, abs, &self.last_endpoint); - self.last_endpoint = to; - Some(PathEvent::QuadraticTo(ctrl, to)) - } - Some(SvgPathSegment::SmoothQuadratic { abs, x, y }) => { - let ctrl = reflect_point(&self.last_endpoint, &self.last_ctrl_point); - self.last_ctrl_point = Some(ctrl); - let to = compute_point(x, y, abs, &self.last_endpoint); - self.last_endpoint = to; - Some(PathEvent::QuadraticTo(ctrl, to)) - } - Some(SvgPathSegment::CurveTo { abs, x1, y1, x2, y2, x, y }) => { - let ctrl0 = compute_point(x1, y1, abs, &self.last_endpoint); - let ctrl1 = compute_point(x2, y2, abs, &self.last_endpoint); - self.last_ctrl_point = Some(ctrl1); - let to = compute_point(x, y, abs, &self.last_endpoint); - self.last_endpoint = to; - Some(PathEvent::CubicTo(ctrl0, ctrl1, to)) - } - Some(SvgPathSegment::SmoothCurveTo { abs, x2, y2, x, y }) => { - let ctrl0 = reflect_point(&self.last_endpoint, &self.last_ctrl_point); - let ctrl1 = compute_point(x2, y2, abs, &self.last_endpoint); - self.last_ctrl_point = Some(ctrl1); - let to = compute_point(x, y, abs, &self.last_endpoint); - self.last_endpoint = to; - Some(PathEvent::CubicTo(ctrl0, ctrl1, to)) - } - Some(SvgPathSegment::ClosePath { abs: _ }) => { - // FIXME(pcwalton): Current endpoint becomes path initial point! - self.last_ctrl_point = None; - Some(PathEvent::Close) - } - Some(SvgPathSegment::EllipticalArc { .. }) => unimplemented!("arcs"), - }; - - fn compute_point(x: f64, y: f64, abs: bool, last_endpoint: &Point2D) - -> Point2D { - let point = Point2D::new(x, y).to_f32(); - if !abs { - *last_endpoint + point.to_vector() - } else { - point - } - } - - fn reflect_point(last_endpoint: &Point2D, last_ctrl_point: &Option>) - -> Point2D { - match *last_ctrl_point { - Some(ref last_ctrl_point) => { - let vector = *last_endpoint - *last_ctrl_point; - *last_endpoint + vector - } - None => *last_endpoint, + UsvgPathSegment::CurveTo { x1, y1, x2, y2, x, y } => { + Some(PathEvent::CubicTo(Point2D::new(x1, y1).to_f32(), + Point2D::new(x2, y2).to_f32(), + Point2D::new(x, y) .to_f32())) } + UsvgPathSegment::ClosePath => Some(PathEvent::Close), } } } @@ -1785,6 +1652,10 @@ impl Iterator for MonotonicConversionIter where I: Iterator Iterator for MonotonicConversionIter where I: Iterator Point2DU4 { Point2DU4(x | (y << 4)) } - - fn x(self) -> u8 { self.0 & 0xf } - fn y(self) -> u8 { self.0 >> 4 } } // Path utilities @@ -2061,7 +1933,6 @@ fn cubic_segment_is_nearly_monotonic(segment: &CubicBezierSegment) -> bool const EPSILON: f32 = 0.1; } -*/ fn cubic_segment_is_nearly_monotonic(segment: &CubicBezierSegment) -> bool { let mut t = None; @@ -2077,6 +1948,24 @@ fn cubic_segment_is_nearly_monotonic(segment: &CubicBezierSegment) -> bool const EPSILON: f32 = 0.01; } +*/ + +const TINY_EPSILON: f32 = 0.1; + +fn cubic_segment_is_tiny(segment: &CubicBezierSegment) -> bool { + let (x0, x1) = segment.fast_bounding_range_x(); + let (y0, y1) = segment.fast_bounding_range_y(); + let (x_delta, y_delta) = (f32::abs(x0 - x1), f32::abs(y0 - y1)); + return x_delta < TINY_EPSILON || y_delta < TINY_EPSILON; +} + +fn quadratic_segment_is_tiny(segment: &QuadraticBezierSegment) -> bool { + let (x0, x1) = segment.fast_bounding_range_x(); + let (y0, y1) = segment.fast_bounding_range_y(); + let (x_delta, y_delta) = (f32::abs(x0 - x1), f32::abs(y0 - y1)); + return x_delta < TINY_EPSILON || y_delta < TINY_EPSILON; + +} // Trivial utilities