diff --git a/Cargo.lock b/Cargo.lock index dcc61cd..6a05688 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2778,6 +2778,19 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.28", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "idna" version = "0.2.3" @@ -2817,9 +2830,9 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "image" -version = "0.24.7" +version = "0.24.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" dependencies = [ "bytemuck", "byteorder", @@ -2827,7 +2840,6 @@ dependencies = [ "exr", "gif", "jpeg-decoder", - "num-rational", "num-traits", "png", "qoi", @@ -3548,6 +3560,24 @@ dependencies = [ "getrandom", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndk" version = "0.7.0" @@ -3903,12 +3933,50 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.47", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "orbclient" version = "0.3.47" @@ -4624,10 +4692,12 @@ dependencies = [ "http-body 0.4.6", "hyper 0.14.28", "hyper-rustls", + "hyper-tls", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -4638,6 +4708,7 @@ dependencies = [ "serde_urlencoded", "system-configuration", "tokio", + "tokio-native-tls", "tokio-rustls", "tokio-socks", "tokio-util", @@ -5188,7 +5259,9 @@ dependencies = [ name = "sg2d" version = "0.1.0" dependencies = [ + "image", "lyon_path", + "reqwest", "serde", "thiserror", ] @@ -5198,8 +5271,10 @@ name = "sg2d-vega" version = "0.1.0" dependencies = [ "csscolorparser", + "image", "lyon_extra", "lyon_path", + "reqwest", "serde", "serde_json", "sg2d", @@ -5215,6 +5290,7 @@ dependencies = [ "cgmath", "dssim", "env_logger", + "etagere", "futures-intrusive", "glyphon", "image", @@ -6242,6 +6318,16 @@ dependencies = [ "tokio-stream", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" diff --git a/Cargo.toml b/Cargo.toml index d25cb3e..c943d69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,5 @@ serde_json = "^1.0" thiserror = "^1.0" lyon_path = "1.0.1" lyon_extra = "1.0.1" -lyon = "1.0.1" \ No newline at end of file +lyon = "1.0.1" +image = { version="0.24.8", default-features = false } diff --git a/examples/scatter-panning/Cargo.lock b/examples/scatter-panning/Cargo.lock index 27e9124..61556e6 100644 --- a/examples/scatter-panning/Cargo.lock +++ b/examples/scatter-panning/Cargo.lock @@ -144,6 +144,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "bit-set" version = "0.5.3" @@ -234,6 +240,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "calloop" version = "0.10.6" @@ -470,6 +482,15 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_logger" version = "0.10.1" @@ -535,6 +556,12 @@ dependencies = [ "zune-inflate", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "fdeflate" version = "0.3.3" @@ -572,6 +599,12 @@ dependencies = [ "spin", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "fontconfig-parser" version = "0.5.3" @@ -637,6 +670,24 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + [[package]] name = "futures-core" version = "0.3.30" @@ -654,12 +705,39 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + [[package]] name = "futures-sink" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" version = "0.2.12" @@ -785,6 +863,25 @@ dependencies = [ "bitflags 2.4.1", ] +[[package]] +name = "h2" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.2.1" @@ -831,17 +928,98 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "image" -version = "0.24.7" +version = "0.24.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" dependencies = [ "bytemuck", "byteorder", @@ -849,7 +1027,6 @@ dependencies = [ "exr", "gif", "jpeg-decoder", - "num-rational", "num-traits", "png", "qoi", @@ -878,6 +1055,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "is-terminal" version = "0.4.10" @@ -1160,6 +1343,12 @@ dependencies = [ "paste", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1211,6 +1400,24 @@ dependencies = [ "getrandom", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndk" version = "0.7.0" @@ -1266,34 +1473,23 @@ dependencies = [ ] [[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" +name = "num-traits" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", - "num-integer", - "num-traits", + "libm", ] [[package]] -name = "num-traits" -version = "0.2.17" +name = "num_cpus" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "autocfg", - "libm", + "hermit-abi", + "libc", ] [[package]] @@ -1398,6 +1594,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "orbclient" version = "0.3.47" @@ -1493,6 +1733,18 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.28" @@ -1694,6 +1946,44 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" +[[package]] +name = "reqwest" +version = "0.11.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "roxmltree" version = "0.18.1" @@ -1773,6 +2063,15 @@ dependencies = [ "winit", ] +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -1798,6 +2097,29 @@ dependencies = [ "tiny-skia", ] +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "self_cell" version = "1.0.3" @@ -1835,11 +2157,25 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sg2d" version = "0.1.0" dependencies = [ + "image", "lyon_path", + "reqwest", "serde", "thiserror", ] @@ -1849,8 +2185,10 @@ name = "sg2d-vega" version = "0.1.0" dependencies = [ "csscolorparser", + "image", "lyon_extra", "lyon_path", + "reqwest", "serde", "serde_json", "sg2d", @@ -1865,6 +2203,7 @@ dependencies = [ "cfg-if", "cgmath", "env_logger", + "etagere", "futures-intrusive", "glyphon", "image", @@ -1890,6 +2229,15 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "slotmap" version = "1.0.7" @@ -1924,6 +2272,16 @@ dependencies = [ "wayland-protocols", ] +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.9.8" @@ -2002,6 +2360,40 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "termcolor" version = "1.4.0" @@ -2082,6 +2474,46 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "toml_datetime" version = "0.6.5" @@ -2099,6 +2531,37 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "ttf-parser" version = "0.19.2" @@ -2141,6 +2604,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-properties" version = "0.1.0" @@ -2171,6 +2643,23 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec_map" version = "0.8.2" @@ -2183,6 +2672,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2744,6 +3242,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "x11-dl" version = "2.21.0" diff --git a/examples/wgpu-winit/Cargo.lock b/examples/wgpu-winit/Cargo.lock index 4bc6015..4f0e969 100644 --- a/examples/wgpu-winit/Cargo.lock +++ b/examples/wgpu-winit/Cargo.lock @@ -144,6 +144,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "bit-set" version = "0.5.3" @@ -234,6 +240,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "calloop" version = "0.10.6" @@ -470,6 +482,15 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_logger" version = "0.10.1" @@ -535,6 +556,12 @@ dependencies = [ "zune-inflate", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "fdeflate" version = "0.3.3" @@ -572,6 +599,12 @@ dependencies = [ "spin", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "fontconfig-parser" version = "0.5.3" @@ -637,6 +670,24 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + [[package]] name = "futures-core" version = "0.3.30" @@ -654,12 +705,39 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + [[package]] name = "futures-sink" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" version = "0.2.12" @@ -785,6 +863,25 @@ dependencies = [ "bitflags 2.4.1", ] +[[package]] +name = "h2" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.2.1" @@ -831,17 +928,98 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "image" -version = "0.24.7" +version = "0.24.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" dependencies = [ "bytemuck", "byteorder", @@ -849,7 +1027,6 @@ dependencies = [ "exr", "gif", "jpeg-decoder", - "num-rational", "num-traits", "png", "qoi", @@ -878,6 +1055,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "is-terminal" version = "0.4.10" @@ -1160,6 +1343,12 @@ dependencies = [ "paste", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1211,6 +1400,24 @@ dependencies = [ "getrandom", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndk" version = "0.7.0" @@ -1266,34 +1473,23 @@ dependencies = [ ] [[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" +name = "num-traits" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", - "num-integer", - "num-traits", + "libm", ] [[package]] -name = "num-traits" -version = "0.2.17" +name = "num_cpus" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "autocfg", - "libm", + "hermit-abi", + "libc", ] [[package]] @@ -1398,6 +1594,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "orbclient" version = "0.3.47" @@ -1493,6 +1733,18 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.28" @@ -1673,6 +1925,44 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" +[[package]] +name = "reqwest" +version = "0.11.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "roxmltree" version = "0.18.1" @@ -1730,6 +2020,15 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -1755,6 +2054,29 @@ dependencies = [ "tiny-skia", ] +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "self_cell" version = "1.0.3" @@ -1792,11 +2114,25 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sg2d" version = "0.1.0" dependencies = [ + "image", "lyon_path", + "reqwest", "serde", "thiserror", ] @@ -1806,8 +2142,10 @@ name = "sg2d-vega" version = "0.1.0" dependencies = [ "csscolorparser", + "image", "lyon_extra", "lyon_path", + "reqwest", "serde", "serde_json", "sg2d", @@ -1822,6 +2160,7 @@ dependencies = [ "cfg-if", "cgmath", "env_logger", + "etagere", "futures-intrusive", "glyphon", "image", @@ -1847,6 +2186,15 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "slotmap" version = "1.0.7" @@ -1881,6 +2229,16 @@ dependencies = [ "wayland-protocols", ] +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.9.8" @@ -1959,6 +2317,40 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "termcolor" version = "1.4.0" @@ -2039,6 +2431,46 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "toml_datetime" version = "0.6.5" @@ -2056,6 +2488,37 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "ttf-parser" version = "0.19.2" @@ -2098,6 +2561,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-properties" version = "0.1.0" @@ -2128,6 +2600,23 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "vec_map" version = "0.8.2" @@ -2140,6 +2629,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2722,6 +3220,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "x11-dl" version = "2.21.0" diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/large_images.png b/sg2d-vega-test-data/vega-scenegraphs/image/large_images.png new file mode 100644 index 0000000..2f98b73 Binary files /dev/null and b/sg2d-vega-test-data/vega-scenegraphs/image/large_images.png differ diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/large_images.sg.json b/sg2d-vega-test-data/vega-scenegraphs/image/large_images.sg.json new file mode 100644 index 0000000..0570fd6 --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/image/large_images.sg.json @@ -0,0 +1,446 @@ +{ + "width": 226, + "height": 226, + "origin": [ + 21, + 5 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 36, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 73, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 109, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 145, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 182, + "y": -200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 164, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 127, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 91, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 55, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 18, + "x2": 200 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 0 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 36 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 73 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 109 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 145 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 182 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 200, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 164, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 127, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 91, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 55, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 18, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 0.5; y: 0.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/js_logo.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/js_logo.png", + "x": -15.909090909090908, + "y": 165.9090909090909 + }, + { + "description": "x: 1.5; y: 1.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/matplotlib.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/matplotlib.png", + "x": 2.27272727272727, + "y": 147.72727272727272 + }, + { + "description": "x: 2.5; y: 2.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/python_logo.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/python_logo.png", + "x": 20.454545454545453, + "y": 129.54545454545453 + }, + { + "description": "x: 3.5; y: 3.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/rust_logo.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/rust_logo.png", + "x": 38.63636363636363, + "y": 111.36363636363637 + }, + { + "description": "x: 4.5; y: 4.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/scipy_logo.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/scipy_logo.png", + "x": 56.81818181818183, + "y": 93.18181818181816 + }, + { + "description": "x: 5.5; y: 5.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VegaFusion-512x512.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VegaFusion-512x512.png", + "x": 75, + "y": 75 + }, + { + "description": "x: 6.5; y: 6.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VG_Black%40512.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VG_Black%40512.png", + "x": 93.18181818181819, + "y": 56.81818181818181 + }, + { + "description": "x: 7.5; y: 7.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VG_Color%40512.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VG_Color%40512.png", + "x": 111.36363636363635, + "y": 38.63636363636365 + }, + { + "description": "x: 8.5; y: 8.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VL_Black%40512.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VL_Black%40512.png", + "x": 129.54545454545453, + "y": 20.45454545454546 + }, + { + "description": "x: 9.5; y: 9.5; img: https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VL_Color%40512.png", + "width": 50, + "height": 50, + "url": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VL_Color%40512.png", + "x": 147.72727272727272, + "y": 2.27272727272727 + } + ], + "marktype": "image", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "fill": "transparent", + "x": 0, + "y": 0, + "width": 200, + "height": 200, + "stroke": "transparent" + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos.png b/sg2d-vega-test-data/vega-scenegraphs/image/logos.png new file mode 100644 index 0000000..ad7c5cb Binary files /dev/null and b/sg2d-vega-test-data/vega-scenegraphs/image/logos.png differ diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos.sg.json b/sg2d-vega-test-data/vega-scenegraphs/image/logos.sg.json new file mode 100644 index 0000000..3d9cedb --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/image/logos.sg.json @@ -0,0 +1,390 @@ +{ + "width": 234, + "height": 234, + "origin": [ + 11, + 23 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 38, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 77, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 115, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 154, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 192, + "y": -200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 162, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 123, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 85, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 46, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 8, + "x2": 200 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 0 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 38 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 77 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 115 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 154 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 192 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 200, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 162, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 123, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 85, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 46, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 8, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 0.5; y: 0.5; img: data/ffox.png", + "width": 50, + "height": 50, + "url": "data/ffox.png", + "x": 13.46153846153846, + "y": 136.53846153846155 + }, + { + "description": "x: 1.5; y: 1.5; img: data/gimp.png", + "width": 50, + "height": 50, + "url": "data/gimp.png", + "x": 90.38461538461537, + "y": 59.61538461538463 + }, + { + "description": "x: 2.5; y: 2.5; img: data/7zip.png", + "width": 50, + "height": 50, + "url": "data/7zip.png", + "x": 167.3076923076923, + "y": -17.307692307692292 + } + ], + "marktype": "image", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "fill": "transparent", + "x": 0, + "y": 0, + "width": 200, + "height": 200, + "stroke": "transparent" + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false.png b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false.png new file mode 100644 index 0000000..f98f036 Binary files /dev/null and b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false.png differ diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false.sg.json b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false.sg.json new file mode 100644 index 0000000..823a842 --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false.sg.json @@ -0,0 +1,393 @@ +{ + "width": 224, + "height": 224, + "origin": [ + 11, + 13 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 38, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 77, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 115, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 154, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 192, + "y": -200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 162, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 123, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 85, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 46, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 8, + "x2": 200 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 0 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 38 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 77 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 115 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 154 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 192 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 200, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 162, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 123, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 85, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 46, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 8, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 0.5; y: 0.5; img: data/ffox.png", + "aspect": false, + "width": 40, + "height": 60, + "url": "data/ffox.png", + "x": 18.46153846153846, + "y": 131.53846153846155 + }, + { + "description": "x: 1.5; y: 1.5; img: data/gimp.png", + "aspect": false, + "width": 150, + "height": 100, + "url": "data/gimp.png", + "x": 40.38461538461537, + "y": 34.61538461538463 + }, + { + "description": "x: 2.5; y: 2.5; img: data/7zip.png", + "aspect": false, + "width": 30, + "height": 30, + "url": "data/7zip.png", + "x": 177.3076923076923, + "y": -7.307692307692291 + } + ], + "marktype": "image", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "fill": "transparent", + "x": 0, + "y": 0, + "width": 200, + "height": 200, + "stroke": "transparent" + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false_align_baseline.png b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false_align_baseline.png new file mode 100644 index 0000000..f2e3381 Binary files /dev/null and b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false_align_baseline.png differ diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false_align_baseline.sg.json b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false_align_baseline.sg.json new file mode 100644 index 0000000..00e07e7 --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_false_align_baseline.sg.json @@ -0,0 +1,399 @@ +{ + "width": 216, + "height": 224, + "origin": [ + 11, + 13 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 38, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 77, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 115, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 154, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 192, + "y": -200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 162, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 123, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 85, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 46, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 8, + "x2": 200 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 0 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 38 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 77 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 115 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 154 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 192 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 200, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 162, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 123, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 85, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 46, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 8, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 0.5; y: 0.5; img: data/ffox.png", + "aspect": false, + "align": "left", + "baseline": "bottom", + "width": 40, + "height": 70, + "url": "data/ffox.png", + "x": 18.46153846153846, + "y": 126.53846153846155 + }, + { + "description": "x: 1.5; y: 1.5; img: data/gimp.png", + "aspect": false, + "align": "right", + "baseline": "middle", + "width": 80, + "height": 60, + "url": "data/gimp.png", + "x": 75.38461538461537, + "y": 54.61538461538463 + }, + { + "description": "x: 2.5; y: 2.5; img: data/7zip.png", + "aspect": false, + "align": "center", + "baseline": "top", + "width": 30, + "height": 30, + "url": "data/7zip.png", + "x": 177.3076923076923, + "y": -7.307692307692291 + } + ], + "marktype": "image", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "fill": "transparent", + "x": 0, + "y": 0, + "width": 200, + "height": 200, + "stroke": "transparent" + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true.png b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true.png new file mode 100644 index 0000000..728f4d5 Binary files /dev/null and b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true.png differ diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true.sg.json b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true.sg.json new file mode 100644 index 0000000..50ba5f8 --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true.sg.json @@ -0,0 +1,399 @@ +{ + "width": 245, + "height": 239, + "origin": [ + 40, + 28 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 38, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 77, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 115, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 154, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 192, + "y": -200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 162, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 123, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 85, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 46, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 8, + "x2": 200 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 0 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 38 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 77 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 115 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 154 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 192 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 200, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 162, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 123, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 85, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 46, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 8, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 0.5; y: 0.5; img: data/ffox.png", + "aspect": true, + "align": "center", + "baseline": "middle", + "width": 40, + "height": 60, + "url": "data/ffox.png", + "x": 18.46153846153846, + "y": 131.53846153846155 + }, + { + "description": "x: 1.5; y: 1.5; img: data/gimp.png", + "aspect": true, + "align": "center", + "baseline": "middle", + "width": 150, + "height": 100, + "url": "data/gimp.png", + "x": 40.38461538461537, + "y": 34.61538461538463 + }, + { + "description": "x: 2.5; y: 2.5; img: data/7zip.png", + "aspect": true, + "align": "center", + "baseline": "middle", + "width": 30, + "height": 30, + "url": "data/7zip.png", + "x": 177.3076923076923, + "y": -7.307692307692291 + } + ], + "marktype": "image", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "fill": "transparent", + "x": 0, + "y": 0, + "width": 200, + "height": 200, + "stroke": "transparent" + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true_align_baseline.png b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true_align_baseline.png new file mode 100644 index 0000000..004f055 Binary files /dev/null and b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true_align_baseline.png differ diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true_align_baseline.sg.json b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true_align_baseline.sg.json new file mode 100644 index 0000000..e94a711 --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/image/logos_sized_aspect_true_align_baseline.sg.json @@ -0,0 +1,436 @@ +{ + "width": 226, + "height": 226, + "origin": [ + 11, + 15 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 38, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 77, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 115, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 154, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 192, + "y": -200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 162, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 123, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 85, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 46, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 8, + "x2": 200 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 0 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 38 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 77 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 115 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 154 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 192 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 200, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 162, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 123, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 85, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 46, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 8, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 0.5; y: 0.5; img: data/ffox.png", + "width": 40, + "height": 70, + "stroke": "gray", + "strokeWidth": 2, + "x": 18.46153846153846, + "y": 126.53846153846155 + }, + { + "description": "x: 1.5; y: 1.5; img: data/gimp.png", + "width": 80, + "height": 60, + "stroke": "gray", + "strokeWidth": 2, + "x": 75.38461538461537, + "y": 54.61538461538463 + }, + { + "description": "x: 2.5; y: 2.5; img: data/7zip.png", + "width": 30, + "height": 30, + "stroke": "gray", + "strokeWidth": 2, + "x": 177.3076923076923, + "y": -7.307692307692291 + } + ], + "marktype": "rect", + "name": "outline", + "role": "mark", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 0.5; y: 0.5; img: data/ffox.png", + "aspect": true, + "align": "left", + "baseline": "bottom", + "width": 40, + "height": 70, + "url": "data/ffox.png", + "x": 18.46153846153846, + "y": 126.53846153846155 + }, + { + "description": "x: 1.5; y: 1.5; img: data/gimp.png", + "aspect": true, + "align": "right", + "baseline": "middle", + "width": 80, + "height": 60, + "url": "data/gimp.png", + "x": 75.38461538461537, + "y": 54.61538461538463 + }, + { + "description": "x: 2.5; y: 2.5; img: data/7zip.png", + "aspect": true, + "align": "center", + "baseline": "top", + "width": 30, + "height": 30, + "url": "data/7zip.png", + "x": 177.3076923076923, + "y": -7.307692307692291 + } + ], + "marktype": "image", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "fill": "transparent", + "x": 0, + "y": 0, + "width": 200, + "height": 200, + "stroke": "transparent" + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/many_images.png b/sg2d-vega-test-data/vega-scenegraphs/image/many_images.png new file mode 100644 index 0000000..2b60a7d Binary files /dev/null and b/sg2d-vega-test-data/vega-scenegraphs/image/many_images.png differ diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/many_images.sg.json b/sg2d-vega-test-data/vega-scenegraphs/image/many_images.sg.json new file mode 100644 index 0000000..3b5b398 --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/image/many_images.sg.json @@ -0,0 +1,758 @@ +{ + "width": 220, + "height": 217, + "origin": [ + 11, + 6 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 33, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 67, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 100, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 133, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 167, + "y": -200, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 200, + "y": -200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 167, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 133, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 100, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 67, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 33, + "x2": 200 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 0, + "x2": 200 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 0 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 33 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 67 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 100 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 133 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 167 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 200 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 200, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 200.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 167, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 133, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 100, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 67, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 33, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 200, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 0.1; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": -3.333333333333333, + "y": 156.66666666666669 + }, + { + "description": "x: 0.1; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": -3.333333333333333, + "y": 90 + }, + { + "description": "x: 0.1; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": -3.333333333333333, + "y": 23.33333333333333 + }, + { + "description": "x: 0.3; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 10, + "y": 156.66666666666669 + }, + { + "description": "x: 0.3; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 10, + "y": 90 + }, + { + "description": "x: 0.3; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 10, + "y": 23.33333333333333 + }, + { + "description": "x: 0.5; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 23.33333333333333, + "y": 156.66666666666669 + }, + { + "description": "x: 0.5; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 23.33333333333333, + "y": 90 + }, + { + "description": "x: 0.5; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 23.33333333333333, + "y": 23.33333333333333 + }, + { + "description": "x: 0.7; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 36.666666666666664, + "y": 156.66666666666669 + }, + { + "description": "x: 0.7; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 36.666666666666664, + "y": 90 + }, + { + "description": "x: 0.7; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 36.666666666666664, + "y": 23.33333333333333 + }, + { + "description": "x: 0.9; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 50, + "y": 156.66666666666669 + }, + { + "description": "x: 0.9; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 50, + "y": 90 + }, + { + "description": "x: 0.9; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 50, + "y": 23.33333333333333 + }, + { + "description": "x: 1.1; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 63.33333333333334, + "y": 156.66666666666669 + }, + { + "description": "x: 1.1; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 63.33333333333334, + "y": 90 + }, + { + "description": "x: 1.1; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 63.33333333333334, + "y": 23.33333333333333 + }, + { + "description": "x: 1.3; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 76.66666666666667, + "y": 156.66666666666669 + }, + { + "description": "x: 1.3; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 76.66666666666667, + "y": 90 + }, + { + "description": "x: 1.3; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 76.66666666666667, + "y": 23.33333333333333 + }, + { + "description": "x: 1.5; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 90, + "y": 156.66666666666669 + }, + { + "description": "x: 1.5; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 90, + "y": 90 + }, + { + "description": "x: 1.5; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 90, + "y": 23.33333333333333 + }, + { + "description": "x: 1.7; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 103.33333333333333, + "y": 156.66666666666669 + }, + { + "description": "x: 1.7; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 103.33333333333333, + "y": 90 + }, + { + "description": "x: 1.7; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 103.33333333333333, + "y": 23.33333333333333 + }, + { + "description": "x: 1.9; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 116.66666666666666, + "y": 156.66666666666669 + }, + { + "description": "x: 1.9; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 116.66666666666666, + "y": 90 + }, + { + "description": "x: 1.9; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 116.66666666666666, + "y": 23.33333333333333 + }, + { + "description": "x: 2.1; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 130, + "y": 156.66666666666669 + }, + { + "description": "x: 2.1; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 130, + "y": 90 + }, + { + "description": "x: 2.1; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 130, + "y": 23.33333333333333 + }, + { + "description": "x: 2.3; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 143.33333333333331, + "y": 156.66666666666669 + }, + { + "description": "x: 2.3; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 143.33333333333331, + "y": 90 + }, + { + "description": "x: 2.3; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 143.33333333333331, + "y": 23.33333333333333 + }, + { + "description": "x: 2.5; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 156.66666666666669, + "y": 156.66666666666669 + }, + { + "description": "x: 2.5; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 156.66666666666669, + "y": 90 + }, + { + "description": "x: 2.5; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 156.66666666666669, + "y": 23.33333333333333 + }, + { + "description": "x: 2.7; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 170, + "y": 156.66666666666669 + }, + { + "description": "x: 2.7; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 170, + "y": 90 + }, + { + "description": "x: 2.7; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 170, + "y": 23.33333333333333 + }, + { + "description": "x: 2.9; y: 0.5; img: data/ffox.png", + "width": 20, + "height": 20, + "url": "data/ffox.png", + "x": 183.33333333333334, + "y": 156.66666666666669 + }, + { + "description": "x: 2.9; y: 1.5; img: data/gimp.png", + "width": 20, + "height": 20, + "url": "data/gimp.png", + "x": 183.33333333333334, + "y": 90 + }, + { + "description": "x: 2.9; y: 2.5; img: data/7zip.png", + "width": 20, + "height": 20, + "url": "data/7zip.png", + "x": 183.33333333333334, + "y": 23.33333333333333 + } + ], + "marktype": "image", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "fill": "transparent", + "stroke": "#ddd", + "x": 0, + "y": 0, + "width": 200, + "height": 200 + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/smooth_false.png b/sg2d-vega-test-data/vega-scenegraphs/image/smooth_false.png new file mode 100644 index 0000000..81401bb Binary files /dev/null and b/sg2d-vega-test-data/vega-scenegraphs/image/smooth_false.png differ diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/smooth_false.sg.json b/sg2d-vega-test-data/vega-scenegraphs/image/smooth_false.sg.json new file mode 100644 index 0000000..9c3379c --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/image/smooth_false.sg.json @@ -0,0 +1,695 @@ +{ + "width": 617, + "height": 617, + "origin": [ + 11, + 6 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 40, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 80, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 120, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 160, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 200, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 240, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 280, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 320, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 360, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 400, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 440, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 480, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 520, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 560, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 600, + "y": -600, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 600.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 600, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 560, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 520, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 480, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 440, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 400, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 360, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 320, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 280, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 240, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 160, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 120, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 80, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 40, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 0, + "x2": 600 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 0 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 40 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 80 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 120 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 160 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 200 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 240 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 280 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 320 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 360 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 400 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 440 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 480 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 520 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 560 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 600 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 600, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 600.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 600, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 560, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 520, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 480, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 440, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 400, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 360, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 320, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 280, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 240, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 160, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 120, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 80, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 40, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 600, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 1.5; y: 1.5; img: data/ffox.png", + "width": 600, + "height": 600, + "smooth": false, + "url": "data/ffox.png", + "x": 0, + "y": 0 + } + ], + "marktype": "image", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "fill": "transparent", + "x": 0, + "y": 0, + "width": 600, + "height": 600, + "stroke": "transparent" + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/smooth_true.png b/sg2d-vega-test-data/vega-scenegraphs/image/smooth_true.png new file mode 100644 index 0000000..81401bb Binary files /dev/null and b/sg2d-vega-test-data/vega-scenegraphs/image/smooth_true.png differ diff --git a/sg2d-vega-test-data/vega-scenegraphs/image/smooth_true.sg.json b/sg2d-vega-test-data/vega-scenegraphs/image/smooth_true.sg.json new file mode 100644 index 0000000..d3f1f67 --- /dev/null +++ b/sg2d-vega-test-data/vega-scenegraphs/image/smooth_true.sg.json @@ -0,0 +1,695 @@ +{ + "width": 617, + "height": 617, + "origin": [ + 11, + 6 + ], + "scenegraph": { + "clip": false, + "interactive": true, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 40, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 80, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 120, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 160, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 200, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 240, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 280, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 320, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 360, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 400, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 440, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 480, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 520, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 560, + "y": -600, + "y2": 0 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 600, + "y": -600, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 600.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 600, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 560, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 520, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 480, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 440, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 400, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 360, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 320, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 280, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 240, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 200, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 160, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 120, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 80, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 40, + "x2": 600 + }, + { + "opacity": 1, + "stroke": "#ddd", + "strokeWidth": 1, + "x": 0, + "y": 0, + "x2": 600 + } + ], + "marktype": "rule", + "role": "axis-grid", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0, + "aria": false + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 0 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 40 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 80 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 120 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 160 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 200 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 240 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 280 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 320 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 360 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 400 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 440 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 480 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 520 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 560 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "y2": 5, + "x": 600 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "x2": 600, + "y": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "bottom", + "x": 0.5, + "y": 600.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "items": [ + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 600, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 560, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 520, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 480, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 440, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 400, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 360, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 320, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 280, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 240, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 200, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 160, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 120, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 80, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 40, + "x": 0, + "x2": -5 + }, + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "y": 0, + "x": 0, + "x2": -5 + } + ], + "marktype": "rule", + "role": "axis-tick", + "zindex": 0 + }, + { + "clip": false, + "interactive": false, + "items": [ + { + "opacity": 1, + "stroke": "#888", + "strokeWidth": 1, + "x": 0, + "y": 600, + "y2": 0 + } + ], + "marktype": "rule", + "role": "axis-domain", + "zindex": 0 + } + ], + "orient": "left", + "x": 0.5, + "y": 0.5 + } + ], + "marktype": "group", + "role": "axis", + "zindex": 0 + }, + { + "clip": false, + "interactive": true, + "items": [ + { + "description": "x: 1.5; y: 1.5; img: data/ffox.png", + "width": 600, + "height": 600, + "smooth": true, + "url": "data/ffox.png", + "x": 0, + "y": 0 + } + ], + "marktype": "image", + "name": "marks", + "role": "mark", + "zindex": 0 + } + ], + "fill": "transparent", + "x": 0, + "y": 0, + "width": 600, + "height": 600, + "stroke": "transparent" + } + ], + "marktype": "group", + "name": "root", + "role": "frame", + "zindex": 0 + } +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-specs/image/large_images.vg.json b/sg2d-vega-test-data/vega-specs/image/large_images.vg.json new file mode 100644 index 0000000..8cc043a --- /dev/null +++ b/sg2d-vega-test-data/vega-specs/image/large_images.vg.json @@ -0,0 +1,165 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "width": 200, + "height": 200, + "style": "cell", + "encode": {"update": {"stroke": {"value": "transparent"}}}, + "data": [ + { + "name": "source_0", + "values": [ + { + "x": 0.5, + "y": 0.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/js_logo.png" + }, + { + "x": 1.5, + "y": 1.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/matplotlib.png" + }, + { + "x": 2.5, + "y": 2.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/python_logo.png" + }, + { + "x": 3.5, + "y": 3.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/rust_logo.png" + }, + { + "x": 4.5, + "y": 4.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/scipy_logo.png" + }, + { + "x": 5.5, + "y": 5.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VegaFusion-512x512.png" + }, + { + "x": 6.5, + "y": 6.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VG_Black%40512.png" + }, + { + "x": 7.5, + "y": 7.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VG_Color%40512.png" + }, + { + "x": 8.5, + "y": 8.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VL_Black%40512.png" + }, + { + "x": 9.5, + "y": 9.5, + "img": "https://filedn.com/lo5VE4SmtWKXIvNsinHVy7F/datasets/logos/VL_Color%40512.png" + } + ] + }, + { + "name": "data_0", + "source": "source_0", + "transform": [ + { + "type": "filter", + "expr": "isValid(datum[\"x\"]) && isFinite(+datum[\"x\"]) && isValid(datum[\"y\"]) && isFinite(+datum[\"y\"])" + } + ] + } + ], + "marks": [ + { + "name": "marks", + "type": "image", + "style": ["image"], + "from": {"data": "data_0"}, + "encode": { + "update": { + "description": { + "signal": "\"x: \" + (format(datum[\"x\"], \"\")) + \"; y: \" + (format(datum[\"y\"], \"\")) + \"; img: \" + (isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"])" + }, + "xc": {"scale": "x", "field": "x"}, + "width": {"value": 50}, + "yc": {"scale": "y", "field": "y"}, + "height": {"value": 50}, + "url": { + "signal": "isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"]" + } + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "linear", + "domain": [0, 11], + "range": [0, {"signal": "width"}], + "nice": true, + "zero": true + }, + { + "name": "y", + "type": "linear", + "domain": [0, 11], + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + } + ], + "axes": [ + { + "scale": "x", + "orient": "bottom", + "gridScale": "y", + "grid": true, + "tickCount": {"signal": "ceil(width/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "x", + "orient": "bottom", + "grid": false, + "labels": false, + "labelFlush": true, + "labelOverlap": true, + "tickCount": {"signal": "ceil(width/40)"}, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "labels": false, + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ] +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-specs/image/logos.vg.json b/sg2d-vega-test-data/vega-specs/image/logos.vg.json new file mode 100644 index 0000000..b9e0835 --- /dev/null +++ b/sg2d-vega-test-data/vega-specs/image/logos.vg.json @@ -0,0 +1,118 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "width": 200, + "height": 200, + "style": "cell", + "encode": {"update": {"stroke": {"value": "transparent"}}}, + "data": [ + { + "name": "source_0", + "values": [ + {"x": 0.5, "y": 0.5, "img": "data/ffox.png"}, + {"x": 1.5, "y": 1.5, "img": "data/gimp.png"}, + {"x": 2.5, "y": 2.5, "img": "data/7zip.png"} + ] + }, + { + "name": "data_0", + "source": "source_0", + "transform": [ + { + "type": "filter", + "expr": "isValid(datum[\"x\"]) && isFinite(+datum[\"x\"]) && isValid(datum[\"y\"]) && isFinite(+datum[\"y\"])" + } + ] + } + ], + "marks": [ + { + "name": "marks", + "type": "image", + "style": ["image"], + "from": {"data": "data_0"}, + "encode": { + "update": { + "description": { + "signal": "\"x: \" + (format(datum[\"x\"], \"\")) + \"; y: \" + (format(datum[\"y\"], \"\")) + \"; img: \" + (isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"])" + }, + "xc": {"scale": "x", "field": "x"}, + "width": {"value": 50}, + "yc": {"scale": "y", "field": "y"}, + "height": {"value": 50}, + "url": { + "signal": "isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"]" + } + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "linear", + "domain": {"data": "data_0", "field": "x"}, + "range": [0, {"signal": "width"}], + "nice": true, + "zero": true + }, + { + "name": "y", + "type": "linear", + "domain": {"data": "data_0", "field": "y"}, + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + } + ], + "axes": [ + { + "scale": "x", + "orient": "bottom", + "gridScale": "y", + "grid": true, + "tickCount": {"signal": "ceil(width/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "x", + "orient": "bottom", + "grid": false, + "labelFlush": true, + "labelOverlap": true, + "labels": false, + "tickCount": {"signal": "ceil(width/40)"}, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "labels": false, + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ] +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-specs/image/logos_sized_aspect_false.vg.json b/sg2d-vega-test-data/vega-specs/image/logos_sized_aspect_false.vg.json new file mode 100644 index 0000000..898a3fc --- /dev/null +++ b/sg2d-vega-test-data/vega-specs/image/logos_sized_aspect_false.vg.json @@ -0,0 +1,119 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "width": 200, + "height": 200, + "style": "cell", + "encode": {"update": {"stroke": {"value": "transparent"}}}, + "data": [ + { + "name": "source_0", + "values": [ + {"x": 0.5, "y": 0.5, "img": "data/ffox.png", "width": 40, "height": 60}, + {"x": 1.5, "y": 1.5, "img": "data/gimp.png", "width": 150, "height": 100}, + {"x": 2.5, "y": 2.5, "img": "data/7zip.png", "width": 30, "height": 30} + ] + }, + { + "name": "data_0", + "source": "source_0", + "transform": [ + { + "type": "filter", + "expr": "isValid(datum[\"x\"]) && isFinite(+datum[\"x\"]) && isValid(datum[\"y\"]) && isFinite(+datum[\"y\"])" + } + ] + } + ], + "marks": [ + { + "name": "marks", + "type": "image", + "style": ["image"], + "from": {"data": "data_0"}, + "encode": { + "update": { + "description": { + "signal": "\"x: \" + (format(datum[\"x\"], \"\")) + \"; y: \" + (format(datum[\"y\"], \"\")) + \"; img: \" + (isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"])" + }, + "aspect": {"value": false}, + "xc": {"scale": "x", "field": "x"}, + "width": {"field": "width"}, + "yc": {"scale": "y", "field": "y"}, + "height": {"field": "height"}, + "url": { + "signal": "isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"]" + } + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "linear", + "domain": {"data": "data_0", "field": "x"}, + "range": [0, {"signal": "width"}], + "nice": true, + "zero": true + }, + { + "name": "y", + "type": "linear", + "domain": {"data": "data_0", "field": "y"}, + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + } + ], + "axes": [ + { + "scale": "x", + "orient": "bottom", + "gridScale": "y", + "grid": true, + "tickCount": {"signal": "ceil(width/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "x", + "orient": "bottom", + "grid": false, + "labelFlush": true, + "labelOverlap": true, + "labels": false, + "tickCount": {"signal": "ceil(width/40)"}, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "labels": false, + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ] +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-specs/image/logos_sized_aspect_false_align_baseline.vg.json b/sg2d-vega-test-data/vega-specs/image/logos_sized_aspect_false_align_baseline.vg.json new file mode 100644 index 0000000..9b90f68 --- /dev/null +++ b/sg2d-vega-test-data/vega-specs/image/logos_sized_aspect_false_align_baseline.vg.json @@ -0,0 +1,121 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "width": 200, + "height": 200, + "style": "cell", + "encode": {"update": {"stroke": {"value": "transparent"}}}, + "data": [ + { + "name": "source_0", + "values": [ + {"x": 0.5, "y": 0.5, "img": "data/ffox.png", "width": 40, "height": 70, "align": "left", "baseline": "bottom"}, + {"x": 1.5, "y": 1.5, "img": "data/gimp.png", "width": 80, "height": 60, "align": "right", "baseline": "middle"}, + {"x": 2.5, "y": 2.5, "img": "data/7zip.png", "width": 30, "height": 30, "align": "center", "baseline": "top"} + ] + }, + { + "name": "data_0", + "source": "source_0", + "transform": [ + { + "type": "filter", + "expr": "isValid(datum[\"x\"]) && isFinite(+datum[\"x\"]) && isValid(datum[\"y\"]) && isFinite(+datum[\"y\"])" + } + ] + } + ], + "marks": [ + { + "name": "marks", + "type": "image", + "style": ["image"], + "from": {"data": "data_0"}, + "encode": { + "update": { + "description": { + "signal": "\"x: \" + (format(datum[\"x\"], \"\")) + \"; y: \" + (format(datum[\"y\"], \"\")) + \"; img: \" + (isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"])" + }, + "aspect": {"value": false}, + "align": {"field": "align"}, + "baseline": {"field": "baseline"}, + "xc": {"scale": "x", "field": "x"}, + "width": {"field": "width"}, + "yc": {"scale": "y", "field": "y"}, + "height": {"field": "height"}, + "url": { + "signal": "isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"]" + } + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "linear", + "domain": {"data": "data_0", "field": "x"}, + "range": [0, {"signal": "width"}], + "nice": true, + "zero": true + }, + { + "name": "y", + "type": "linear", + "domain": {"data": "data_0", "field": "y"}, + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + } + ], + "axes": [ + { + "scale": "x", + "orient": "bottom", + "gridScale": "y", + "grid": true, + "tickCount": {"signal": "ceil(width/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "x", + "orient": "bottom", + "grid": false, + "labelFlush": true, + "labelOverlap": true, + "labels": false, + "tickCount": {"signal": "ceil(width/40)"}, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "labels": false, + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ] +} diff --git a/sg2d-vega-test-data/vega-specs/image/logos_sized_aspect_true_align_baseline.vg.json b/sg2d-vega-test-data/vega-specs/image/logos_sized_aspect_true_align_baseline.vg.json new file mode 100644 index 0000000..7e8ca2f --- /dev/null +++ b/sg2d-vega-test-data/vega-specs/image/logos_sized_aspect_true_align_baseline.vg.json @@ -0,0 +1,139 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "width": 200, + "height": 200, + "style": "cell", + "encode": {"update": {"stroke": {"value": "transparent"}}}, + "data": [ + { + "name": "source_0", + "values": [ + {"x": 0.5, "y": 0.5, "img": "data/ffox.png", "width": 40, "height": 70, "align": "left", "baseline": "bottom"}, + {"x": 1.5, "y": 1.5, "img": "data/gimp.png", "width": 80, "height": 60, "align": "right", "baseline": "middle"}, + {"x": 2.5, "y": 2.5, "img": "data/7zip.png", "width": 30, "height": 30, "align": "center", "baseline": "top"} + ] + }, + { + "name": "data_0", + "source": "source_0", + "transform": [ + { + "type": "filter", + "expr": "isValid(datum[\"x\"]) && isFinite(+datum[\"x\"]) && isValid(datum[\"y\"]) && isFinite(+datum[\"y\"])" + } + ] + } + ], + "marks": [ + { + "name": "outline", + "type": "rect", + "from": {"data": "data_0"}, + "encode": { + "update": { + "description": { + "signal": "\"x: \" + (format(datum[\"x\"], \"\")) + \"; y: \" + (format(datum[\"y\"], \"\")) + \"; img: \" + (isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"])" + }, + "xc": {"scale": "x", "field": "x"}, + "yc": {"scale": "y", "field": "y"}, + "width": {"field": "width"}, + "height": {"field": "height"}, + "stroke": {"value": "gray"}, + "strokeWidth": {"value": 2} + } + } + }, + { + "name": "marks", + "type": "image", + "style": ["image"], + "from": {"data": "data_0"}, + "encode": { + "update": { + "description": { + "signal": "\"x: \" + (format(datum[\"x\"], \"\")) + \"; y: \" + (format(datum[\"y\"], \"\")) + \"; img: \" + (isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"])" + }, + "aspect": {"value": true}, + "align": {"field": "align"}, + "baseline": {"field": "baseline"}, + "xc": {"scale": "x", "field": "x"}, + "width": {"field": "width"}, + "yc": {"scale": "y", "field": "y"}, + "height": {"field": "height"}, + "url": { + "signal": "isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"]" + } + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "linear", + "domain": {"data": "data_0", "field": "x"}, + "range": [0, {"signal": "width"}], + "nice": true, + "zero": true + }, + { + "name": "y", + "type": "linear", + "domain": {"data": "data_0", "field": "y"}, + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + } + ], + "axes": [ + { + "scale": "x", + "orient": "bottom", + "gridScale": "y", + "grid": true, + "tickCount": {"signal": "ceil(width/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "x", + "orient": "bottom", + "grid": false, + "labelFlush": true, + "labelOverlap": true, + "labels": false, + "tickCount": {"signal": "ceil(width/40)"}, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "labels": false, + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ] +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-specs/image/many_images.vg.json b/sg2d-vega-test-data/vega-specs/image/many_images.vg.json new file mode 100644 index 0000000..bf634f2 --- /dev/null +++ b/sg2d-vega-test-data/vega-specs/image/many_images.vg.json @@ -0,0 +1,159 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "width": 200, + "height": 200, + "style": "cell", + "data": [ + { + "name": "source_0", + "values": [ + {"x": 0.1, "y": 0.5, "img": "data/ffox.png"}, + {"x": 0.1, "y": 1.5, "img": "data/gimp.png"}, + {"x": 0.1, "y": 2.5, "img": "data/7zip.png"}, + {"x": 0.3, "y": 0.5, "img": "data/ffox.png"}, + {"x": 0.3, "y": 1.5, "img": "data/gimp.png"}, + {"x": 0.3, "y": 2.5, "img": "data/7zip.png"}, + {"x": 0.5, "y": 0.5, "img": "data/ffox.png"}, + {"x": 0.5, "y": 1.5, "img": "data/gimp.png"}, + {"x": 0.5, "y": 2.5, "img": "data/7zip.png"}, + {"x": 0.7, "y": 0.5, "img": "data/ffox.png"}, + {"x": 0.7, "y": 1.5, "img": "data/gimp.png"}, + {"x": 0.7, "y": 2.5, "img": "data/7zip.png"}, + {"x": 0.9, "y": 0.5, "img": "data/ffox.png"}, + {"x": 0.9, "y": 1.5, "img": "data/gimp.png"}, + {"x": 0.9, "y": 2.5, "img": "data/7zip.png"}, + {"x": 1.1, "y": 0.5, "img": "data/ffox.png"}, + {"x": 1.1, "y": 1.5, "img": "data/gimp.png"}, + {"x": 1.1, "y": 2.5, "img": "data/7zip.png"}, + {"x": 1.3, "y": 0.5, "img": "data/ffox.png"}, + {"x": 1.3, "y": 1.5, "img": "data/gimp.png"}, + {"x": 1.3, "y": 2.5, "img": "data/7zip.png"}, + {"x": 1.5, "y": 0.5, "img": "data/ffox.png"}, + {"x": 1.5, "y": 1.5, "img": "data/gimp.png"}, + {"x": 1.5, "y": 2.5, "img": "data/7zip.png"}, + {"x": 1.7, "y": 0.5, "img": "data/ffox.png"}, + {"x": 1.7, "y": 1.5, "img": "data/gimp.png"}, + {"x": 1.7, "y": 2.5, "img": "data/7zip.png"}, + {"x": 1.9, "y": 0.5, "img": "data/ffox.png"}, + {"x": 1.9, "y": 1.5, "img": "data/gimp.png"}, + {"x": 1.9, "y": 2.5, "img": "data/7zip.png"}, + {"x": 2.1, "y": 0.5, "img": "data/ffox.png"}, + {"x": 2.1, "y": 1.5, "img": "data/gimp.png"}, + {"x": 2.1, "y": 2.5, "img": "data/7zip.png"}, + {"x": 2.3, "y": 0.5, "img": "data/ffox.png"}, + {"x": 2.3, "y": 1.5, "img": "data/gimp.png"}, + {"x": 2.3, "y": 2.5, "img": "data/7zip.png"}, + {"x": 2.5, "y": 0.5, "img": "data/ffox.png"}, + {"x": 2.5, "y": 1.5, "img": "data/gimp.png"}, + {"x": 2.5, "y": 2.5, "img": "data/7zip.png"}, + {"x": 2.7, "y": 0.5, "img": "data/ffox.png"}, + {"x": 2.7, "y": 1.5, "img": "data/gimp.png"}, + {"x": 2.7, "y": 2.5, "img": "data/7zip.png"}, + {"x": 2.9, "y": 0.5, "img": "data/ffox.png"}, + {"x": 2.9, "y": 1.5, "img": "data/gimp.png"}, + {"x": 2.9, "y": 2.5, "img": "data/7zip.png"} + ] + }, + { + "name": "data_0", + "source": "source_0", + "transform": [ + { + "type": "filter", + "expr": "isValid(datum[\"x\"]) && isFinite(+datum[\"x\"]) && isValid(datum[\"y\"]) && isFinite(+datum[\"y\"])" + } + ] + } + ], + "marks": [ + { + "name": "marks", + "type": "image", + "style": ["image"], + "from": {"data": "data_0"}, + "encode": { + "update": { + "description": { + "signal": "\"x: \" + (format(datum[\"x\"], \"\")) + \"; y: \" + (format(datum[\"y\"], \"\")) + \"; img: \" + (isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"])" + }, + "xc": {"scale": "x", "field": "x"}, + "yc": {"scale": "y", "field": "y"}, + "width": {"value": 20}, + "height": {"value": 20}, + "url": { + "signal": "isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"]" + } + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "linear", + "domain": [0, 3], + "range": [0, {"signal": "width"}], + "nice": true, + "zero": true + }, + { + "name": "y", + "type": "linear", + "domain": [0, 3], + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + } + ], + "axes": [ + { + "scale": "x", + "orient": "bottom", + "gridScale": "y", + "grid": true, + "tickCount": {"signal": "ceil(width/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "x", + "orient": "bottom", + "grid": false, + "labels": false, + "labelFlush": true, + "labelOverlap": true, + "tickCount": {"signal": "ceil(width/40)"}, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "labels": false, + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ] +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-specs/image/smooth_false.vg.json b/sg2d-vega-test-data/vega-specs/image/smooth_false.vg.json new file mode 100644 index 0000000..62d32b7 --- /dev/null +++ b/sg2d-vega-test-data/vega-specs/image/smooth_false.vg.json @@ -0,0 +1,117 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "width": 600, + "height": 600, + "style": "cell", + "encode": {"update": {"stroke": {"value": "transparent"}}}, + "data": [ + { + "name": "source_0", + "values": [ + {"x": 1.5, "y": 1.5, "img": "data/ffox.png"} + ] + }, + { + "name": "data_0", + "source": "source_0", + "transform": [ + { + "type": "filter", + "expr": "isValid(datum[\"x\"]) && isFinite(+datum[\"x\"]) && isValid(datum[\"y\"]) && isFinite(+datum[\"y\"])" + } + ] + } + ], + "marks": [ + { + "name": "marks", + "type": "image", + "style": ["image"], + "from": {"data": "data_0"}, + "encode": { + "update": { + "description": { + "signal": "\"x: \" + (format(datum[\"x\"], \"\")) + \"; y: \" + (format(datum[\"y\"], \"\")) + \"; img: \" + (isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"])" + }, + "width": {"value": 600}, + "height": {"value": 600}, + "xc": {"scale": "x", "field": "x"}, + "yc": {"scale": "y", "field": "y"}, + "smooth": {"value": false}, + "url": { + "signal": "isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"]" + } + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "linear", + "domain": [0, 3], + "range": [0, {"signal": "width"}], + "nice": true, + "zero": true + }, + { + "name": "y", + "type": "linear", + "domain": [0, 3], + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + } + ], + "axes": [ + { + "scale": "x", + "orient": "bottom", + "gridScale": "y", + "grid": true, + "tickCount": {"signal": "ceil(width/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "x", + "orient": "bottom", + "grid": false, + "labelFlush": true, + "labelOverlap": true, + "labels": false, + "tickCount": {"signal": "ceil(width/40)"}, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "labels": false, + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ] +} \ No newline at end of file diff --git a/sg2d-vega-test-data/vega-specs/image/smooth_true.vg.json b/sg2d-vega-test-data/vega-specs/image/smooth_true.vg.json new file mode 100644 index 0000000..48095b9 --- /dev/null +++ b/sg2d-vega-test-data/vega-specs/image/smooth_true.vg.json @@ -0,0 +1,117 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "width": 600, + "height": 600, + "style": "cell", + "encode": {"update": {"stroke": {"value": "transparent"}}}, + "data": [ + { + "name": "source_0", + "values": [ + {"x": 1.5, "y": 1.5, "img": "data/ffox.png"} + ] + }, + { + "name": "data_0", + "source": "source_0", + "transform": [ + { + "type": "filter", + "expr": "isValid(datum[\"x\"]) && isFinite(+datum[\"x\"]) && isValid(datum[\"y\"]) && isFinite(+datum[\"y\"])" + } + ] + } + ], + "marks": [ + { + "name": "marks", + "type": "image", + "style": ["image"], + "from": {"data": "data_0"}, + "encode": { + "update": { + "description": { + "signal": "\"x: \" + (format(datum[\"x\"], \"\")) + \"; y: \" + (format(datum[\"y\"], \"\")) + \"; img: \" + (isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"])" + }, + "width": {"value": 600}, + "height": {"value": 600}, + "xc": {"scale": "x", "field": "x"}, + "yc": {"scale": "y", "field": "y"}, + "smooth": {"value": true}, + "url": { + "signal": "isValid(datum[\"img\"]) ? datum[\"img\"] : \"\"+datum[\"img\"]" + } + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "linear", + "domain": [0, 3], + "range": [0, {"signal": "width"}], + "nice": true, + "zero": true + }, + { + "name": "y", + "type": "linear", + "domain": [0, 3], + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + } + ], + "axes": [ + { + "scale": "x", + "orient": "bottom", + "gridScale": "y", + "grid": true, + "tickCount": {"signal": "ceil(width/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "gridScale": "x", + "grid": true, + "tickCount": {"signal": "ceil(height/40)"}, + "domain": false, + "labels": false, + "aria": false, + "maxExtent": 0, + "minExtent": 0, + "ticks": false, + "zindex": 0 + }, + { + "scale": "x", + "orient": "bottom", + "grid": false, + "labelFlush": true, + "labelOverlap": true, + "labels": false, + "tickCount": {"signal": "ceil(width/40)"}, + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "labels": false, + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ] +} \ No newline at end of file diff --git a/sg2d-vega/Cargo.toml b/sg2d-vega/Cargo.toml index 8a4a6d1..d5836e6 100644 --- a/sg2d-vega/Cargo.toml +++ b/sg2d-vega/Cargo.toml @@ -13,3 +13,5 @@ csscolorparser = "0.6.2" serde_json = { version = "1.0.111" } lyon_extra = { workspace = true } lyon_path = { workspace = true, features = ["serialization"]} +reqwest = { version = "0.11.23", features = ["blocking"] } +image = { workspace = true, default-features = false, features = ["png"] } diff --git a/sg2d-vega/src/marks/arc.rs b/sg2d-vega/src/marks/arc.rs index d208474..efa721d 100644 --- a/sg2d-vega/src/marks/arc.rs +++ b/sg2d-vega/src/marks/arc.rs @@ -3,7 +3,7 @@ use crate::marks::mark::{VegaMarkContainer, VegaMarkItem}; use serde::{Deserialize, Serialize}; use sg2d::marks::arc::ArcMark; use sg2d::marks::mark::SceneMark; -use sg2d::value::EncodingValue; +use sg2d::marks::value::EncodingValue; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/sg2d-vega/src/marks/area.rs b/sg2d-vega/src/marks/area.rs index 33338bd..9625b95 100644 --- a/sg2d-vega/src/marks/area.rs +++ b/sg2d-vega/src/marks/area.rs @@ -4,7 +4,7 @@ use crate::marks::values::StrokeDashSpec; use serde::{Deserialize, Serialize}; use sg2d::marks::area::{AreaMark, AreaOrientation}; use sg2d::marks::mark::SceneMark; -use sg2d::value::{EncodingValue, StrokeCap, StrokeJoin}; +use sg2d::marks::value::{EncodingValue, StrokeCap, StrokeJoin}; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/sg2d-vega/src/marks/group.rs b/sg2d-vega/src/marks/group.rs index dd062e9..7db121b 100644 --- a/sg2d-vega/src/marks/group.rs +++ b/sg2d-vega/src/marks/group.rs @@ -58,9 +58,8 @@ impl VegaGroupItem { VegaMark::Trail(mark) => { vec![mark.to_scene_graph(new_origin)?] } - _ => { - println!("Mark type not yet supported: {:?}", item); - continue; + VegaMark::Image(mark) => { + vec![mark.to_scene_graph(new_origin)?] } }; marks.extend(item_marks); diff --git a/sg2d-vega/src/marks/image.rs b/sg2d-vega/src/marks/image.rs new file mode 100644 index 0000000..d4cb074 --- /dev/null +++ b/sg2d-vega/src/marks/image.rs @@ -0,0 +1,116 @@ +use crate::error::VegaSceneGraphError; +use crate::marks::mark::{VegaMarkContainer, VegaMarkItem}; +use reqwest::blocking::Client; +use serde::{Deserialize, Serialize}; +use sg2d::marks::image::{ImageMark, RgbaImage}; +use sg2d::marks::mark::SceneMark; +use sg2d::marks::value::{EncodingValue, ImageAlign, ImageBaseline}; + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct VegaImageItem { + pub url: String, + #[serde(default)] + pub x: f32, + #[serde(default)] + pub y: f32, + pub width: Option, + pub height: Option, + #[serde(default = "default_true")] + pub aspect: bool, + #[serde(default = "default_true")] + pub smooth: bool, + #[serde(default)] + pub align: ImageAlign, + #[serde(default)] + pub baseline: ImageBaseline, + pub zindex: Option, +} + +fn default_true() -> bool { + true +} + +impl VegaMarkItem for VegaImageItem {} + +impl VegaMarkContainer { + pub fn to_scene_graph(&self, origin: [f32; 2]) -> Result { + let name = self + .name + .clone() + .unwrap_or_else(|| "image_mark".to_string()); + + let first = self.items.first(); + let aspect = first.map(|f| f.aspect).unwrap_or(true); + let smooth = first.map(|f| f.smooth).unwrap_or(true); + + let mut x: Vec = Vec::new(); + let mut y: Vec = Vec::new(); + let mut width: Vec = Vec::new(); + let mut height: Vec = Vec::new(); + let mut align: Vec = Vec::new(); + let mut baseline: Vec = Vec::new(); + let mut images: Vec = Vec::new(); + let mut zindex = Vec::::new(); + + let client = Client::new(); + + for item in &self.items { + x.push(item.x + origin[0]); + y.push(item.y + origin[1]); + align.push(item.align); + baseline.push(item.baseline); + + // load image + let url = if item.url.starts_with("data/") { + // built-in vega dataset + format!("https://vega.github.io/vega-datasets/{}", &item.url) + } else { + item.url.clone() + }; + + // TODO: don't panic when loading image and converting to rgba8 + let img_data = client.get(&url).send().unwrap().bytes().unwrap().to_vec(); + let diffuse_image = image::load_from_memory(img_data.as_slice()).unwrap(); + + let rgba_img = diffuse_image.to_rgba8(); + let img_width = rgba_img.width(); + let img_height = rgba_img.height(); + images.push(RgbaImage::from_image(&rgba_img)); + + // Push width/height + width.push(item.width.unwrap_or(img_width as f32)); + height.push(item.height.unwrap_or(img_height as f32)); + + if let Some(v) = item.zindex { + zindex.push(v); + } + } + + let len = self.items.len(); + + let indices = if zindex.len() == len { + let mut indices: Vec = (0..len).collect(); + indices.sort_by_key(|i| zindex[*i]); + Some(indices) + } else { + None + }; + + Ok(SceneMark::Image(Box::new(ImageMark { + name, + clip: self.clip, + len: self.items.len() as u32, + aspect, + smooth, + align: EncodingValue::Array { values: align }, + baseline: EncodingValue::Array { values: baseline }, + image: EncodingValue::Array { values: images }, + x: EncodingValue::Array { values: x }, + y: EncodingValue::Array { values: y }, + width: EncodingValue::Array { values: width }, + height: EncodingValue::Array { values: height }, + indices, + }))) + } +} diff --git a/sg2d-vega/src/marks/line.rs b/sg2d-vega/src/marks/line.rs index f73e966..dcde38e 100644 --- a/sg2d-vega/src/marks/line.rs +++ b/sg2d-vega/src/marks/line.rs @@ -4,7 +4,7 @@ use crate::marks::values::StrokeDashSpec; use serde::{Deserialize, Serialize}; use sg2d::marks::line::LineMark; use sg2d::marks::mark::SceneMark; -use sg2d::value::{EncodingValue, StrokeCap, StrokeJoin}; +use sg2d::marks::value::{EncodingValue, StrokeCap, StrokeJoin}; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/sg2d-vega/src/marks/mark.rs b/sg2d-vega/src/marks/mark.rs index 50c56ec..50e8cc4 100644 --- a/sg2d-vega/src/marks/mark.rs +++ b/sg2d-vega/src/marks/mark.rs @@ -1,6 +1,7 @@ use crate::marks::arc::VegaArcItem; use crate::marks::area::VegaAreaItem; use crate::marks::group::VegaGroupItem; +use crate::marks::image::VegaImageItem; use crate::marks::line::VegaLineItem; use crate::marks::path::VegaPathItem; use crate::marks::rect::VegaRectItem; @@ -19,7 +20,7 @@ pub trait VegaMarkItem {} pub enum VegaMark { Arc(VegaMarkContainer), Area(VegaMarkContainer), - Image, + Image(VegaMarkContainer), Group(VegaMarkContainer), Line(VegaMarkContainer), Path(VegaMarkContainer), diff --git a/sg2d-vega/src/marks/mod.rs b/sg2d-vega/src/marks/mod.rs index 8ad2fd0..b9720e7 100644 --- a/sg2d-vega/src/marks/mod.rs +++ b/sg2d-vega/src/marks/mod.rs @@ -1,6 +1,7 @@ pub mod arc; pub mod area; pub mod group; +pub mod image; pub mod line; pub mod mark; pub mod path; diff --git a/sg2d-vega/src/marks/path.rs b/sg2d-vega/src/marks/path.rs index 129755d..837210a 100644 --- a/sg2d-vega/src/marks/path.rs +++ b/sg2d-vega/src/marks/path.rs @@ -6,7 +6,7 @@ use lyon_path::geom::Angle; use serde::{Deserialize, Serialize}; use sg2d::marks::mark::SceneMark; use sg2d::marks::path::{PathMark, PathTransform}; -use sg2d::value::{EncodingValue, StrokeCap, StrokeJoin}; +use sg2d::marks::value::{EncodingValue, StrokeCap, StrokeJoin}; use std::collections::HashSet; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] diff --git a/sg2d-vega/src/marks/rect.rs b/sg2d-vega/src/marks/rect.rs index 8a6c072..d90a883 100644 --- a/sg2d-vega/src/marks/rect.rs +++ b/sg2d-vega/src/marks/rect.rs @@ -3,7 +3,7 @@ use crate::marks::mark::{VegaMarkContainer, VegaMarkItem}; use serde::{Deserialize, Serialize}; use sg2d::marks::mark::SceneMark; use sg2d::marks::rect::RectMark; -use sg2d::value::EncodingValue; +use sg2d::marks::value::EncodingValue; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/sg2d-vega/src/marks/rule.rs b/sg2d-vega/src/marks/rule.rs index d19f8e6..7617705 100644 --- a/sg2d-vega/src/marks/rule.rs +++ b/sg2d-vega/src/marks/rule.rs @@ -4,7 +4,7 @@ use crate::marks::values::StrokeDashSpec; use serde::{Deserialize, Serialize}; use sg2d::marks::mark::SceneMark; use sg2d::marks::rule::RuleMark; -use sg2d::value::{EncodingValue, StrokeCap}; +use sg2d::marks::value::{EncodingValue, StrokeCap}; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/sg2d-vega/src/marks/shape.rs b/sg2d-vega/src/marks/shape.rs index 52e6484..642181b 100644 --- a/sg2d-vega/src/marks/shape.rs +++ b/sg2d-vega/src/marks/shape.rs @@ -4,7 +4,7 @@ use crate::marks::symbol::parse_svg_path; use serde::{Deserialize, Serialize}; use sg2d::marks::mark::SceneMark; use sg2d::marks::path::{PathMark, PathTransform}; -use sg2d::value::{EncodingValue, StrokeCap, StrokeJoin}; +use sg2d::marks::value::{EncodingValue, StrokeCap, StrokeJoin}; use std::collections::HashSet; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] diff --git a/sg2d-vega/src/marks/symbol.rs b/sg2d-vega/src/marks/symbol.rs index 88c4f47..9275045 100644 --- a/sg2d-vega/src/marks/symbol.rs +++ b/sg2d-vega/src/marks/symbol.rs @@ -10,7 +10,7 @@ use sg2d::marks::group::{GroupBounds, SceneGroup}; use sg2d::marks::line::LineMark; use sg2d::marks::mark::SceneMark; use sg2d::marks::symbol::{SymbolMark, SymbolShape}; -use sg2d::value::{EncodingValue, StrokeCap, StrokeJoin}; +use sg2d::marks::value::{EncodingValue, StrokeCap, StrokeJoin}; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/sg2d-vega/src/marks/text.rs b/sg2d-vega/src/marks/text.rs index e16f988..3f5827f 100644 --- a/sg2d-vega/src/marks/text.rs +++ b/sg2d-vega/src/marks/text.rs @@ -3,7 +3,7 @@ use crate::marks::mark::{VegaMarkContainer, VegaMarkItem}; use serde::{Deserialize, Serialize}; use sg2d::marks::mark::SceneMark; use sg2d::marks::text::{FontStyleSpec, FontWeightSpec, TextAlignSpec, TextBaselineSpec, TextMark}; -use sg2d::value::EncodingValue; +use sg2d::marks::value::EncodingValue; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/sg2d-vega/src/marks/trail.rs b/sg2d-vega/src/marks/trail.rs index ce6c081..7937ac9 100644 --- a/sg2d-vega/src/marks/trail.rs +++ b/sg2d-vega/src/marks/trail.rs @@ -3,7 +3,7 @@ use crate::marks::mark::{VegaMarkContainer, VegaMarkItem}; use serde::{Deserialize, Serialize}; use sg2d::marks::mark::SceneMark; use sg2d::marks::trail::TrailMark; -use sg2d::value::EncodingValue; +use sg2d::marks::value::EncodingValue; #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/sg2d-wgpu/Cargo.toml b/sg2d-wgpu/Cargo.toml index 19c9e14..746d2c5 100644 --- a/sg2d-wgpu/Cargo.toml +++ b/sg2d-wgpu/Cargo.toml @@ -21,6 +21,7 @@ cgmath = "0.18.0" itertools = "0.12.0" image = "0.24.7" futures-intrusive = "^0.5" +etagere = "0.2.10" # glyphon branch that includes text rotation support: https://github.com/jonmmease/glyphon/pull/1 glyphon = { git = "https://github.com/jonmmease/glyphon.git", rev="c468f5dacd4130b27a29b098c4de3f4d5c146209" } diff --git a/sg2d-wgpu/src/canvas.rs b/sg2d-wgpu/src/canvas.rs index 84e26b2..ba6bfe5 100644 --- a/sg2d-wgpu/src/canvas.rs +++ b/sg2d-wgpu/src/canvas.rs @@ -15,14 +15,17 @@ use winit::window::Window; use crate::error::Sg2dWgpuError; use crate::marks::arc::{ArcInstance, ArcShader}; use crate::marks::basic_mark::BasicMarkRenderer; +use crate::marks::image::ImageShader; use crate::marks::instanced_mark::InstancedMarkRenderer; use crate::marks::path::PathShader; use crate::marks::rect::{RectInstance, RectShader}; use crate::marks::rule::{RuleInstance, RuleShader}; use crate::marks::symbol::{SymbolInstance, SymbolShader}; use crate::marks::text::{TextInstance, TextMarkRenderer}; +use crate::marks::texture_mark::TextureMarkRenderer; use sg2d::marks::arc::ArcMark; use sg2d::marks::area::AreaMark; +use sg2d::marks::image::ImageMark; use sg2d::marks::line::LineMark; use sg2d::marks::path::PathMark; use sg2d::marks::trail::TrailMark; @@ -42,6 +45,7 @@ pub struct CanvasUniform { pub enum MarkRenderer { Basic(BasicMarkRenderer), Instanced(InstancedMarkRenderer), + Texture(TextureMarkRenderer), Text(TextMarkRenderer), } @@ -172,6 +176,17 @@ pub trait Canvas { Ok(()) } + fn add_image_mark(&mut self, mark: &ImageMark) -> Result<(), Sg2dWgpuError> { + self.add_mark_renderer(MarkRenderer::Texture(TextureMarkRenderer::new( + self.device(), + *self.uniform(), + self.texture_format(), + self.sample_count(), + Box::new(ImageShader::from_image_mark(mark)?), + ))); + Ok(()) + } + fn add_group_mark(&mut self, group: &SceneGroup) -> Result<(), Sg2dWgpuError> { for mark in &group.marks { match mark { @@ -202,6 +217,9 @@ pub trait Canvas { SceneMark::Text(mark) => { self.add_text_mark(mark)?; } + SceneMark::Image(mark) => { + self.add_image_mark(mark)?; + } SceneMark::Group(group) => { self.add_group_mark(group)?; } @@ -484,6 +502,13 @@ impl WindowCanvas { renderer.render(&self.device, &view, None) } } + MarkRenderer::Texture(renderer) => { + if self.sample_count > 1 { + renderer.render(&self.device, &self.multisampled_framebuffer, Some(&view)) + } else { + renderer.render(&self.device, &view, None) + } + } MarkRenderer::Text(renderer) => { if self.sample_count > 1 { renderer.render( @@ -687,6 +712,17 @@ impl PngCanvas { mark.render(&self.device, &self.texture_view, None) } } + MarkRenderer::Texture(renderer) => { + if self.sample_count > 1 { + renderer.render( + &self.device, + &self.multisampled_framebuffer, + Some(&self.texture_view), + ) + } else { + renderer.render(&self.device, &self.texture_view, None) + } + } MarkRenderer::Text(mark) => { if self.sample_count > 1 { mark.render( diff --git a/sg2d-wgpu/src/error.rs b/sg2d-wgpu/src/error.rs index 40d1c4d..1844357 100644 --- a/sg2d-wgpu/src/error.rs +++ b/sg2d-wgpu/src/error.rs @@ -17,4 +17,7 @@ pub enum Sg2dWgpuError { #[error("lyon tessellation error")] TessellationError(#[from] TessellationError), + + #[error("Image allocation error: {0}")] + ImageAllocationError(String), } diff --git a/sg2d-wgpu/src/marks/image.rs b/sg2d-wgpu/src/marks/image.rs new file mode 100644 index 0000000..2d98d6a --- /dev/null +++ b/sg2d-wgpu/src/marks/image.rs @@ -0,0 +1,272 @@ +use crate::error::Sg2dWgpuError; +use crate::marks::texture_mark::{TextureMarkBatch, TextureMarkShader}; +use etagere::Size; +use itertools::izip; +use sg2d::marks::image::ImageMark; +use sg2d::marks::value::{ImageAlign, ImageBaseline}; +use wgpu::{Extent3d, FilterMode, VertexBufferLayout}; + +#[repr(C)] +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +pub struct ImageVertex { + pub position: [f32; 2], + pub tex_coord: [f32; 2], +} + +const VERTEX_ATTRIBUTES: [wgpu::VertexAttribute; 2] = wgpu::vertex_attr_array![ + 0 => Float32x2, // position + 1 => Float32x2, // tex_coord +]; + +impl ImageVertex { + pub fn desc() -> VertexBufferLayout<'static> { + VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &VERTEX_ATTRIBUTES, + } + } +} + +pub struct ImageShader { + verts: Vec, + indices: Vec, + shader: String, + vertex_entry_point: String, + fragment_entry_point: String, + batches: Vec, + texture_size: Extent3d, + mag_filter: wgpu::FilterMode, +} + +impl ImageShader { + pub fn from_image_mark(mark: &ImageMark) -> Result { + let mut verts: Vec = Vec::new(); + let mut indices: Vec = Vec::new(); + let mut batches: Vec = Vec::new(); + let aspect = mark.aspect; + + // Compute texture size + let limits = wgpu::Limits::downlevel_webgl2_defaults(); + let texture_size = Extent3d { + width: limits.max_texture_dimension_1d, + height: limits.max_texture_dimension_2d, + depth_or_array_layers: 1, + }; + + // Allocate image for texture + let mut texture_image = image::RgbaImage::new(texture_size.width, texture_size.height); + let mut atlas_allocator = etagere::AtlasAllocator::new(Size::new( + texture_size.width as i32, + texture_size.height as i32, + )); + + let mut start_index = indices.len() as u32; + for (img, x, y, width, height, baseline, align) in izip!( + mark.image_iter(), + mark.x_iter(), + mark.y_iter(), + mark.width_iter(), + mark.height_iter(), + mark.baseline_iter(), + mark.align_iter(), + ) { + let Some(rgba_image) = img.to_image() else { + continue; + }; + + let allocation = match atlas_allocator + .allocate(Size::new(img.width as i32, img.height as i32)) + { + Some(allocation) => allocation, + None => { + // Current allocator is full + // Add previous batch + batches.push(TextureMarkBatch { + indices: start_index..indices.len() as u32, + image: image::DynamicImage::ImageRgba8(texture_image), + }); + + // create new allocator, new texture image, new batch + atlas_allocator = etagere::AtlasAllocator::new(Size::new( + texture_size.width as i32, + texture_size.height as i32, + )); + + let Some(allocation) = + atlas_allocator.allocate(Size::new(img.width as i32, img.height as i32)) + else { + if img.width > texture_size.width || img.height > texture_size.height { + return Err(Sg2dWgpuError::ImageAllocationError(format!( + "Image dimensions ({}, {}) exceed the maximum size of ({}, {})", + img.width, img.height, texture_size.width, texture_size.height + ))); + } else { + return Err(Sg2dWgpuError::ImageAllocationError( + "Unknown error".to_string(), + )); + } + }; + + // Create a new texture image + texture_image = image::RgbaImage::new(texture_size.width, texture_size.height); + + // update start_index + start_index = indices.len() as u32; + + allocation + } + }; + + // Write image to allocated portion of final texture image + let p0 = allocation.rectangle.min; + let p1 = allocation.rectangle.max; + let x0 = p0.x; + let x1 = p1.x.min(x0 + img.width as i32); + let y0 = p0.y; + let y1 = p1.y.min(y0 + img.height as i32); + for (src_x, dest_x) in (x0..x1).enumerate() { + for (src_y, dest_y) in (y0..y1).enumerate() { + texture_image.put_pixel( + dest_x as u32, + dest_y as u32, + *rgba_image.get_pixel(src_x as u32, src_y as u32), + ); + } + } + + // Compute texture coordinates + let tex_x0 = x0 as f32 / texture_size.width as f32; + let tex_x1 = x1 as f32 / texture_size.width as f32; + let tex_y0 = y0 as f32 / texture_size.height as f32; + let tex_y1 = y1 as f32 / texture_size.height as f32; + + // Vertex index offset + let offset = verts.len() as u16; + + // Compute image left + let left = match *align { + ImageAlign::Left => *x, + ImageAlign::Center => *x - *width / 2.0, + ImageAlign::Right => *x - *width, + }; + // Compute image top + let top = match *baseline { + ImageBaseline::Top => *y, + ImageBaseline::Middle => *y - *height / 2.0, + ImageBaseline::Bottom => *y - *height, + }; + + // Adjust position and dimensions if aspect ratio should be preserved + let (left, top, width, height) = if aspect { + let img_aspect = img.width as f32 / img.height as f32; + let outline_aspect = *width / *height; + if img_aspect > outline_aspect { + // image is wider than the box, so we scale + // image to box width and center vertically + let aspect_height = *width / img_aspect; + let aspect_top = top + (*height - aspect_height) / 2.0; + (left, aspect_top, *width, aspect_height) + } else if img_aspect < outline_aspect { + // image is taller than the box, so we scale + // image to box height an center horizontally + let aspect_width = *height * img_aspect; + let aspect_left = left + (*width - aspect_width) / 2.0; + (aspect_left, top, aspect_width, *height) + } else { + (left, top, *width, *height) + } + } else { + (left, top, *width, *height) + }; + + verts.push(ImageVertex { + position: [left, top], + tex_coord: [tex_x0, tex_y0], + }); + // Lower left + verts.push(ImageVertex { + position: [left, top + height], + tex_coord: [tex_x0, tex_y1], + }); + // Lower right + verts.push(ImageVertex { + position: [left + width, top + height], + tex_coord: [tex_x1, tex_y1], + }); + // Upper right + verts.push(ImageVertex { + position: [left + width, top], + tex_coord: [tex_x1, tex_y0], + }); + + // Indices + indices.push(offset); + indices.push(offset + 1); + indices.push(offset + 2); + + indices.push(offset); + indices.push(offset + 2); + indices.push(offset + 3); + } + batches.push(TextureMarkBatch { + indices: start_index..indices.len() as u32, + image: image::DynamicImage::ImageRgba8(texture_image), + }); + + Ok(Self { + verts, + indices, + batches, + texture_size, + shader: include_str!("image.wgsl").to_string(), + vertex_entry_point: "vs_main".to_string(), + fragment_entry_point: "fs_main".to_string(), + mag_filter: if mark.smooth { + wgpu::FilterMode::Linear + } else { + wgpu::FilterMode::Nearest + }, + }) + } +} + +impl TextureMarkShader for ImageShader { + type Vertex = ImageVertex; + + fn verts(&self) -> &[Self::Vertex] { + self.verts.as_slice() + } + + fn indices(&self) -> &[u16] { + self.indices.as_slice() + } + + fn shader(&self) -> &str { + self.shader.as_str() + } + + fn vertex_entry_point(&self) -> &str { + self.vertex_entry_point.as_str() + } + + fn fragment_entry_point(&self) -> &str { + self.fragment_entry_point.as_str() + } + + fn vertex_desc(&self) -> VertexBufferLayout<'static> { + ImageVertex::desc() + } + + fn batches(&self) -> &[TextureMarkBatch] { + self.batches.as_slice() + } + + fn texture_size(&self) -> Extent3d { + self.texture_size + } + + fn mag_filter(&self) -> FilterMode { + self.mag_filter + } +} diff --git a/sg2d-wgpu/src/marks/image.wgsl b/sg2d-wgpu/src/marks/image.wgsl new file mode 100644 index 0000000..de293e7 --- /dev/null +++ b/sg2d-wgpu/src/marks/image.wgsl @@ -0,0 +1,43 @@ +struct ChartUniform { + size: vec2, + scale: f32, + _pad: f32, // for 16 byte alignment +}; + +@group(0) @binding(0) +var chart_uniforms: ChartUniform; + +struct VertexInput { + @location(0) position: vec2, + @location(1) tex_coords: vec2, +} + +struct VertexOutput { + @builtin(position) clip_position: vec4, + @location(0) tex_coords: vec2, +} + +@vertex +fn vs_main( + model: VertexInput, +) -> VertexOutput { + var out: VertexOutput; + out.tex_coords = model.tex_coords; + let normalized_pos = vec2( + 2.0 * model.position[0] / chart_uniforms.size[0] - 1.0, + 2.0 * (chart_uniforms.size[1] - model.position[1]) / chart_uniforms.size[1] - 1.0, + ); + out.clip_position = vec4(normalized_pos, 0.0, 1.0); + return out; +} + +// Fragment shader +@group(1) @binding(0) +var t_diffuse: texture_2d; +@group(1) @binding(1) +var s_diffuse: sampler; + +@fragment +fn fs_main(in: VertexOutput) -> @location(0) vec4 { + return textureSample(t_diffuse, s_diffuse, in.tex_coords); +} diff --git a/sg2d-wgpu/src/marks/instanced_mark.rs b/sg2d-wgpu/src/marks/instanced_mark.rs index 30a0619..19c06b4 100644 --- a/sg2d-wgpu/src/marks/instanced_mark.rs +++ b/sg2d-wgpu/src/marks/instanced_mark.rs @@ -68,13 +68,6 @@ impl InstancedMarkRenderer { label: Some("uniform_bind_group"), }); - let _render_pipeline_layout = - device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&uniform_layout], - push_constant_ranges: &[], - }); - // Shaders let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("Shader"), diff --git a/sg2d-wgpu/src/marks/mod.rs b/sg2d-wgpu/src/marks/mod.rs index 7f3f753..326c031 100644 --- a/sg2d-wgpu/src/marks/mod.rs +++ b/sg2d-wgpu/src/marks/mod.rs @@ -1,8 +1,10 @@ pub mod arc; pub mod basic_mark; +pub mod image; pub mod instanced_mark; pub mod path; pub mod rect; pub mod rule; pub mod symbol; pub mod text; +pub mod texture_mark; diff --git a/sg2d-wgpu/src/marks/path.rs b/sg2d-wgpu/src/marks/path.rs index 00d4569..c393a86 100644 --- a/sg2d-wgpu/src/marks/path.rs +++ b/sg2d-wgpu/src/marks/path.rs @@ -13,7 +13,7 @@ use sg2d::marks::area::{AreaMark, AreaOrientation}; use sg2d::marks::line::LineMark; use sg2d::marks::path::PathMark; use sg2d::marks::trail::TrailMark; -use sg2d::value::{StrokeCap, StrokeJoin}; +use sg2d::marks::value::{StrokeCap, StrokeJoin}; use wgpu::VertexBufferLayout; #[repr(C)] diff --git a/sg2d-wgpu/src/marks/rule.rs b/sg2d-wgpu/src/marks/rule.rs index 7361d0e..0677823 100644 --- a/sg2d-wgpu/src/marks/rule.rs +++ b/sg2d-wgpu/src/marks/rule.rs @@ -1,7 +1,7 @@ use crate::marks::instanced_mark::InstancedMarkShader; use itertools::izip; use sg2d::marks::rule::RuleMark; -use sg2d::value::StrokeCap; +use sg2d::marks::value::StrokeCap; use wgpu::VertexBufferLayout; #[repr(C)] diff --git a/sg2d-wgpu/src/marks/texture_mark.rs b/sg2d-wgpu/src/marks/texture_mark.rs new file mode 100644 index 0000000..25f0fda --- /dev/null +++ b/sg2d-wgpu/src/marks/texture_mark.rs @@ -0,0 +1,283 @@ +use crate::canvas::CanvasUniform; +use std::ops::Range; +use wgpu::util::DeviceExt; +use wgpu::{CommandBuffer, Device, Extent3d, ImageDataLayout, TextureFormat, TextureView}; + +#[derive(Clone)] +pub struct TextureMarkBatch { + pub indices: Range, + pub image: image::DynamicImage, +} + +pub trait TextureMarkShader { + type Vertex: bytemuck::Pod + bytemuck::Zeroable; + fn verts(&self) -> &[Self::Vertex]; + fn indices(&self) -> &[u16]; + fn batches(&self) -> &[TextureMarkBatch]; + fn texture_size(&self) -> Extent3d; + fn shader(&self) -> &str; + fn vertex_entry_point(&self) -> &str; + fn fragment_entry_point(&self) -> &str; + fn vertex_desc(&self) -> wgpu::VertexBufferLayout<'static>; + + fn mag_filter(&self) -> wgpu::FilterMode { + wgpu::FilterMode::Linear + } + fn min_filter(&self) -> wgpu::FilterMode { + wgpu::FilterMode::Nearest + } + fn mipmap_filter(&self) -> wgpu::FilterMode { + wgpu::FilterMode::Nearest + } +} + +pub struct TextureMarkRenderer { + render_pipeline: wgpu::RenderPipeline, + vertex_buffer: wgpu::Buffer, + index_buffer: wgpu::Buffer, + batches: Vec, + uniform_bind_group: wgpu::BindGroup, + texture: wgpu::Texture, + texture_size: wgpu::Extent3d, + texture_bind_group: wgpu::BindGroup, +} + +impl TextureMarkRenderer { + pub fn new( + device: &Device, + uniform: CanvasUniform, + texture_format: TextureFormat, + sample_count: u32, + mark_shader: Box>, + ) -> Self + where + V: bytemuck::Pod + bytemuck::Zeroable, + { + // Uniforms + let uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Uniform Buffer"), + contents: bytemuck::cast_slice(&[uniform]), + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + }); + + let uniform_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + }], + label: Some("chart_uniform_layout"), + }); + + let uniform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: &uniform_layout, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: uniform_buffer.as_entire_binding(), + }], + label: Some("uniform_bind_group"), + }); + + // Create Texture + let texture = device.create_texture(&wgpu::TextureDescriptor { + size: mark_shader.texture_size(), + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8Unorm, + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, + label: Some("diffuse_texture"), + view_formats: &[], + }); + let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default()); + + let sampler = device.create_sampler(&wgpu::SamplerDescriptor { + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: mark_shader.mag_filter(), + min_filter: mark_shader.min_filter(), + mipmap_filter: mark_shader.mipmap_filter(), + ..Default::default() + }); + + let texture_bind_group_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + multisampled: false, + view_dimension: wgpu::TextureViewDimension::D2, + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + // This should match the filterable field of the + // corresponding Texture entry above. + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: None, + }, + ], + label: Some("texture_bind_group_layout"), + }); + + let texture_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: &texture_bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&texture_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Sampler(&sampler), + }, + ], + label: Some("texture_bind_group"), + }); + + // Shaders + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("Shader"), + source: wgpu::ShaderSource::Wgsl(mark_shader.shader().into()), + }); + + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Render Pipeline Layout"), + bind_group_layouts: &[&uniform_layout, &texture_bind_group_layout], + push_constant_ranges: &[], + }); + + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Render Pipeline"), + layout: Some(&render_pipeline_layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: mark_shader.vertex_entry_point(), + buffers: &[mark_shader.vertex_desc()], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: mark_shader.fragment_entry_point(), + targets: &[Some(wgpu::ColorTargetState { + format: texture_format, + blend: Some(wgpu::BlendState::ALPHA_BLENDING), + write_mask: wgpu::ColorWrites::ALL, + })], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + strip_index_format: None, + front_face: wgpu::FrontFace::Ccw, + cull_mode: Some(wgpu::Face::Back), + polygon_mode: wgpu::PolygonMode::Fill, + unclipped_depth: false, + conservative: false, + }, + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: sample_count, + mask: !0, + alpha_to_coverage_enabled: false, + }, + multiview: None, + }); + + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(mark_shader.verts()), + usage: wgpu::BufferUsages::VERTEX, + }); + + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(mark_shader.indices()), + usage: wgpu::BufferUsages::INDEX, + }); + + Self { + render_pipeline, + vertex_buffer, + index_buffer, + batches: Vec::from(mark_shader.batches()), + uniform_bind_group, + texture, + texture_size: mark_shader.texture_size(), + texture_bind_group, + } + } + + pub fn render( + &self, + device: &Device, + texture_view: &TextureView, + resolve_target: Option<&TextureView>, + ) -> CommandBuffer { + let mut mark_encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("Mark Render Encoder"), + }); + + for batch in self.batches.iter() { + let temp_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Temp Buffer"), + contents: batch.image.to_rgba8().as_raw(), + usage: wgpu::BufferUsages::COPY_SRC, + }); + mark_encoder.copy_buffer_to_texture( + wgpu::ImageCopyBuffer { + buffer: &temp_buffer, + layout: ImageDataLayout { + offset: 0, + bytes_per_row: Some(4 * self.texture_size.width), + rows_per_image: Some(self.texture_size.height), + }, + }, + wgpu::ImageCopyTexture { + texture: &self.texture, + mip_level: 0, + origin: wgpu::Origin3d::ZERO, + aspect: wgpu::TextureAspect::All, + }, + self.texture_size, + ); + + { + let mut render_pass = mark_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("Mark Render Pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: texture_view, + resolve_target, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: wgpu::StoreOp::Store, + }, + })], + depth_stencil_attachment: None, + occlusion_query_set: None, + timestamp_writes: None, + }); + + render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_bind_group(0, &self.uniform_bind_group, &[]); + render_pass.set_bind_group(1, &self.texture_bind_group, &[]); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); + render_pass + .set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); + render_pass.draw_indexed(batch.indices.clone(), 0, 0..1); + } + } + + mark_encoder.finish() + } +} diff --git a/sg2d-wgpu/tests/test_image_baselines.rs b/sg2d-wgpu/tests/test_image_baselines.rs index 5d0b814..52d0821 100644 --- a/sg2d-wgpu/tests/test_image_baselines.rs +++ b/sg2d-wgpu/tests/test_image_baselines.rs @@ -98,6 +98,15 @@ mod test_image_baselines { case("trail", "trail_stocks", 0.0005), case("trail", "trail_stocks_opacity", 0.0005), + + case("image", "logos", 0.001), + case("image", "logos_sized_aspect_false", 0.001), + case("image", "logos_sized_aspect_false_align_baseline", 0.001), + case("image", "logos_sized_aspect_true_align_baseline", 0.001), + case("image", "smooth_false", 0.03), // vl-convert/resvg doesn't support smooth=false + case("image", "smooth_true", 0.001), + case("image", "many_images", 0.001), + case("image", "large_images", 0.001), )] fn test_image_baseline(category: &str, spec_name: &str, tolerance: f64) { let specs_dir = format!( diff --git a/sg2d/Cargo.toml b/sg2d/Cargo.toml index 8a7b699..0ae491f 100644 --- a/sg2d/Cargo.toml +++ b/sg2d/Cargo.toml @@ -9,3 +9,5 @@ edition = "2021" thiserror = { workspace = true } serde = { workspace = true } lyon_path = { workspace = true, features = ["serialization"] } +image = { workspace = true, features = ["png"] } +reqwest = { version="0.11.23" , features = ["blocking"]} diff --git a/sg2d/src/lib.rs b/sg2d/src/lib.rs index bcf1969..466274b 100644 --- a/sg2d/src/lib.rs +++ b/sg2d/src/lib.rs @@ -1,4 +1,3 @@ pub mod error; pub mod marks; pub mod scene_graph; -pub mod value; diff --git a/sg2d/src/marks/arc.rs b/sg2d/src/marks/arc.rs index 43c66aa..f4fd5d1 100644 --- a/sg2d/src/marks/arc.rs +++ b/sg2d/src/marks/arc.rs @@ -1,4 +1,4 @@ -use crate::value::EncodingValue; +use crate::marks::value::EncodingValue; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/sg2d/src/marks/area.rs b/sg2d/src/marks/area.rs index e7982f2..a9115a7 100644 --- a/sg2d/src/marks/area.rs +++ b/sg2d/src/marks/area.rs @@ -1,4 +1,4 @@ -use crate::value::{EncodingValue, StrokeCap, StrokeJoin}; +use crate::marks::value::{EncodingValue, StrokeCap, StrokeJoin}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/sg2d/src/marks/image.rs b/sg2d/src/marks/image.rs new file mode 100644 index 0000000..7f3b387 --- /dev/null +++ b/sg2d/src/marks/image.rs @@ -0,0 +1,67 @@ +use crate::marks::value::{EncodingValue, ImageAlign, ImageBaseline}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct ImageMark { + pub name: String, + pub clip: bool, + pub len: u32, + pub aspect: bool, + pub smooth: bool, + pub image: EncodingValue, + pub x: EncodingValue, + pub y: EncodingValue, + pub width: EncodingValue, + pub height: EncodingValue, + pub align: EncodingValue, + pub baseline: EncodingValue, + pub indices: Option>, +} + +impl ImageMark { + pub fn image_iter(&self) -> Box + '_> { + self.image.as_iter(self.len as usize, self.indices.as_ref()) + } + pub fn x_iter(&self) -> Box + '_> { + self.x.as_iter(self.len as usize, self.indices.as_ref()) + } + pub fn y_iter(&self) -> Box + '_> { + self.y.as_iter(self.len as usize, self.indices.as_ref()) + } + pub fn width_iter(&self) -> Box + '_> { + self.width.as_iter(self.len as usize, self.indices.as_ref()) + } + pub fn height_iter(&self) -> Box + '_> { + self.height + .as_iter(self.len as usize, self.indices.as_ref()) + } + pub fn align_iter(&self) -> Box + '_> { + self.align.as_iter(self.len as usize, self.indices.as_ref()) + } + pub fn baseline_iter(&self) -> Box + '_> { + self.baseline + .as_iter(self.len as usize, self.indices.as_ref()) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RgbaImage { + pub width: u32, + pub height: u32, + pub data: Vec, +} + +impl RgbaImage { + pub fn to_image(&self) -> Option { + image::RgbaImage::from_raw(self.width, self.height, self.data.clone()) + } + + pub fn from_image(img: &image::RgbaImage) -> Self { + Self { + width: img.width(), + height: img.height(), + data: img.to_vec(), + } + } +} diff --git a/sg2d/src/marks/line.rs b/sg2d/src/marks/line.rs index 3c4dc95..2774728 100644 --- a/sg2d/src/marks/line.rs +++ b/sg2d/src/marks/line.rs @@ -1,4 +1,4 @@ -use crate::value::{EncodingValue, StrokeCap, StrokeJoin}; +use crate::marks::value::{EncodingValue, StrokeCap, StrokeJoin}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/sg2d/src/marks/mark.rs b/sg2d/src/marks/mark.rs index c442bff..63c3b46 100644 --- a/sg2d/src/marks/mark.rs +++ b/sg2d/src/marks/mark.rs @@ -1,6 +1,7 @@ use crate::marks::arc::ArcMark; use crate::marks::area::AreaMark; use crate::marks::group::SceneGroup; +use crate::marks::image::ImageMark; use crate::marks::line::LineMark; use crate::marks::path::PathMark; use crate::marks::rect::RectMark; @@ -21,5 +22,6 @@ pub enum SceneMark { Rect(RectMark), Rule(RuleMark), Text(Box), + Image(Box), Group(SceneGroup), } diff --git a/sg2d/src/marks/mod.rs b/sg2d/src/marks/mod.rs index c2e0a4f..6dab7cf 100644 --- a/sg2d/src/marks/mod.rs +++ b/sg2d/src/marks/mod.rs @@ -1,6 +1,7 @@ pub mod arc; pub mod area; pub mod group; +pub mod image; pub mod line; pub mod mark; pub mod path; @@ -9,3 +10,4 @@ pub mod rule; pub mod symbol; pub mod text; pub mod trail; +pub mod value; diff --git a/sg2d/src/marks/path.rs b/sg2d/src/marks/path.rs index b94e9ed..9a746e8 100644 --- a/sg2d/src/marks/path.rs +++ b/sg2d/src/marks/path.rs @@ -1,4 +1,4 @@ -use crate::value::{EncodingValue, StrokeCap, StrokeJoin}; +use crate::marks::value::{EncodingValue, StrokeCap, StrokeJoin}; use lyon_path::geom::euclid::{Transform2D, UnknownUnit}; use serde::{Deserialize, Serialize}; diff --git a/sg2d/src/marks/rect.rs b/sg2d/src/marks/rect.rs index d5acbe2..341f4e2 100644 --- a/sg2d/src/marks/rect.rs +++ b/sg2d/src/marks/rect.rs @@ -1,4 +1,4 @@ -use crate::value::EncodingValue; +use crate::marks::value::EncodingValue; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -67,7 +67,7 @@ impl Default for RectMark { width: EncodingValue::Scalar { value: 0.0 }, height: EncodingValue::Scalar { value: 0.0 }, fill: EncodingValue::Scalar { - value: [0.0, 0.0, 0.0, 1.0], + value: [0.0, 0.0, 0.0, 0.0], }, stroke: EncodingValue::Scalar { value: [0.0, 0.0, 0.0, 0.0], diff --git a/sg2d/src/marks/rule.rs b/sg2d/src/marks/rule.rs index c7c668b..432cac6 100644 --- a/sg2d/src/marks/rule.rs +++ b/sg2d/src/marks/rule.rs @@ -1,4 +1,4 @@ -use crate::value::{EncodingValue, StrokeCap}; +use crate::marks::value::{EncodingValue, StrokeCap}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/sg2d/src/marks/symbol.rs b/sg2d/src/marks/symbol.rs index 54878ed..dacb81b 100644 --- a/sg2d/src/marks/symbol.rs +++ b/sg2d/src/marks/symbol.rs @@ -1,4 +1,4 @@ -use crate::value::EncodingValue; +use crate::marks::value::EncodingValue; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/sg2d/src/marks/text.rs b/sg2d/src/marks/text.rs index f93cf7f..d3da14b 100644 --- a/sg2d/src/marks/text.rs +++ b/sg2d/src/marks/text.rs @@ -1,4 +1,4 @@ -use crate::value::EncodingValue; +use crate::marks::value::EncodingValue; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/sg2d/src/marks/trail.rs b/sg2d/src/marks/trail.rs index d1b3f40..9d4a8ab 100644 --- a/sg2d/src/marks/trail.rs +++ b/sg2d/src/marks/trail.rs @@ -1,4 +1,4 @@ -use crate::value::EncodingValue; +use crate::marks::value::EncodingValue; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/sg2d/src/value.rs b/sg2d/src/marks/value.rs similarity index 75% rename from sg2d/src/value.rs rename to sg2d/src/marks/value.rs index 5d85420..7673329 100644 --- a/sg2d/src/value.rs +++ b/sg2d/src/marks/value.rs @@ -40,3 +40,21 @@ pub enum StrokeJoin { Miter, Round, } + +#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum ImageAlign { + #[default] + Left, + Center, + Right, +} + +#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum ImageBaseline { + #[default] + Top, + Middle, + Bottom, +}