Merge branch 'dev' (unicode_support feature)
This commit is contained in:
commit
625daa58e3
10 changed files with 985 additions and 160 deletions
393
Cargo.lock
generated
393
Cargo.lock
generated
|
@ -9,7 +9,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24606928a235e73cdef55a0c909719cadd72fce573e5713d58cb2952d8f5794c"
|
checksum = "24606928a235e73cdef55a0c909719cadd72fce573e5713d58cb2952d8f5794c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph_rasterizer",
|
"ab_glyph_rasterizer",
|
||||||
"owned_ttf_parser 0.15.0",
|
"owned_ttf_parser 0.15.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -30,6 +30,15 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alsa"
|
name = "alsa"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
@ -114,27 +123,32 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base-x"
|
name = "base-x"
|
||||||
version = "0.2.10"
|
version = "0.2.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc19a4937b4fbd3fe3379793130e42060d10627a360f2127802b10b87e7baf74"
|
checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bindgen"
|
name = "bindgen"
|
||||||
version = "0.59.2"
|
version = "0.53.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8"
|
checksum = "c72a978d268b1d70b0e963217e60fdabd9523a941457a6c42a7315d15c7e89e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cexpr",
|
"cexpr",
|
||||||
|
"cfg-if 0.1.10",
|
||||||
"clang-sys",
|
"clang-sys",
|
||||||
|
"clap",
|
||||||
|
"env_logger",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lazycell",
|
"lazycell",
|
||||||
|
"log",
|
||||||
"peeking_take_while",
|
"peeking_take_while",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"shlex",
|
"shlex",
|
||||||
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -157,21 +171,21 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.9.1"
|
version = "3.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytecount"
|
name = "bytecount"
|
||||||
version = "0.6.2"
|
version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e"
|
checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.9.1"
|
version = "1.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc"
|
checksum = "a5377c8865e74a160d21f29c2d40669f53286db6eab59b88540cbb12ffc8b835"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
|
@ -181,9 +195,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.1.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bzip2"
|
name = "bzip2"
|
||||||
|
@ -218,9 +232,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "camino"
|
name = "camino"
|
||||||
version = "1.0.8"
|
version = "1.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07fd178c5af4d59e83498ef15cf3f154e1a6f9d091270cb86283c65ef44e9ef0"
|
checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -242,7 +256,7 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"camino",
|
"camino",
|
||||||
"cargo-platform",
|
"cargo-platform",
|
||||||
"semver 1.0.9",
|
"semver 1.0.12",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
@ -264,11 +278,11 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cexpr"
|
name = "cexpr"
|
||||||
version = "0.6.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nom",
|
"nom 5.1.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -294,13 +308,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clang-sys"
|
name = "clang-sys"
|
||||||
version = "1.3.1"
|
version = "0.29.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21"
|
checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob",
|
"glob",
|
||||||
"libc",
|
"libc",
|
||||||
"libloading 0.7.3",
|
"libloading 0.5.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -324,6 +338,15 @@ version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4bfbf56724aa9eca8afa4fcfadeb479e722935bb2a0900c2d37e0cc477af0688"
|
checksum = "4bfbf56724aa9eca8afa4fcfadeb479e722935bb2a0900c2d37e0cc477af0688"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cmake"
|
||||||
|
version = "0.1.48"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cocoa"
|
name = "cocoa"
|
||||||
version = "0.24.0"
|
version = "0.24.0"
|
||||||
|
@ -481,9 +504,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "coreaudio-sys"
|
name = "coreaudio-sys"
|
||||||
version = "0.2.10"
|
version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3dff444d80630d7073077d38d40b4501fd518bd2b922c2a55edcc8b0f7be57e6"
|
checksum = "17f73df0f29f4c3c374854f076c47dc018f19acaa63538880dba0937ad4fa8d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
]
|
]
|
||||||
|
@ -524,9 +547,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam"
|
name = "crossbeam"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845"
|
checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
|
@ -538,9 +561,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.5.4"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
|
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
|
@ -548,9 +571,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
|
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"crossbeam-epoch",
|
"crossbeam-epoch",
|
||||||
|
@ -559,23 +582,23 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-epoch"
|
name = "crossbeam-epoch"
|
||||||
version = "0.9.8"
|
version = "0.9.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
|
checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"lazy_static",
|
|
||||||
"memoffset",
|
"memoffset",
|
||||||
|
"once_cell",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-queue"
|
name = "crossbeam-queue"
|
||||||
version = "0.3.5"
|
version = "0.3.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2"
|
checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
|
@ -583,12 +606,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.8"
|
version = "0.8.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
|
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"lazy_static",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -762,9 +785,22 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.6.1"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"humantime",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "error-chain"
|
name = "error-chain"
|
||||||
|
@ -802,23 +838,21 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"instant",
|
"instant",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.23"
|
version = "1.0.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af"
|
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"libc",
|
"miniz_oxide 0.5.3",
|
||||||
"miniz_oxide 0.5.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -832,9 +866,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flume"
|
name = "flume"
|
||||||
version = "0.10.12"
|
version = "0.10.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a"
|
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
@ -864,6 +898,27 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "freetype"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6"
|
||||||
|
dependencies = [
|
||||||
|
"freetype-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "freetype-sys"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a"
|
||||||
|
dependencies = [
|
||||||
|
"cmake",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.21"
|
version = "0.3.21"
|
||||||
|
@ -878,9 +933,9 @@ checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
|
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
@ -965,9 +1020,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gif"
|
name = "gif"
|
||||||
version = "0.11.3"
|
version = "0.11.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b"
|
checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"color_quant",
|
"color_quant",
|
||||||
"weezl",
|
"weezl",
|
||||||
|
@ -1172,6 +1227,15 @@ version = "3.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549"
|
checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||||
|
dependencies = [
|
||||||
|
"quick-error",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -1197,9 +1261,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.24.2"
|
version = "0.24.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28edd9d7bc256be2502e325ac0628bde30b7001b9b52e0abe31a1a9dc2701212"
|
checksum = "7e30ca2ecf7666107ff827a8e481de6a132a9b687ed3bb20bb1c144a36c00964"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -1207,12 +1271,11 @@ dependencies = [
|
||||||
"exr",
|
"exr",
|
||||||
"gif",
|
"gif",
|
||||||
"jpeg-decoder 0.2.6",
|
"jpeg-decoder 0.2.6",
|
||||||
"num-iter",
|
"num-rational 0.4.1",
|
||||||
"num-rational 0.4.0",
|
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"png 0.17.5",
|
"png 0.17.5",
|
||||||
"scoped_threadpool",
|
"scoped_threadpool",
|
||||||
"tiff 0.7.2",
|
"tiff 0.7.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1295,9 +1358,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.57"
|
version = "0.3.59"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397"
|
checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
@ -1339,9 +1402,19 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.125"
|
version = "0.2.126"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
|
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libloading"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
|
@ -1375,9 +1448,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
version = "0.5.4"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
|
@ -1420,9 +1493,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lyon_geom"
|
name = "lyon_geom"
|
||||||
version = "0.17.6"
|
version = "0.17.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce99ce77c22bfd8f39a95b9c749dffbfc3e2491ea30c874764c801a8b1485489"
|
checksum = "71d89ccbdafd83d259403e22061be27bccc3254bba65cdc5303250c4227c8c8e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"euclid",
|
"euclid",
|
||||||
|
@ -1546,9 +1619,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.5.1"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
|
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
]
|
]
|
||||||
|
@ -1595,10 +1668,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mpd_info_screen"
|
name = "mpd_info_screen"
|
||||||
version = "0.2.20"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"freetype",
|
||||||
"ggez",
|
"ggez",
|
||||||
"image 0.24.2",
|
"image 0.24.3",
|
||||||
"structopt",
|
"structopt",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1749,6 +1824,16 @@ dependencies = [
|
||||||
"memoffset",
|
"memoffset",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "5.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "7.1.1"
|
version = "7.1.1"
|
||||||
|
@ -1813,9 +1898,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-rational"
|
name = "num-rational"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
|
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
|
@ -1916,9 +2001,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.10.0"
|
version = "1.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-float"
|
name = "ordered-float"
|
||||||
|
@ -1949,11 +2034,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owned_ttf_parser"
|
name = "owned_ttf_parser"
|
||||||
version = "0.15.0"
|
version = "0.15.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fb1e509cfe7a12db2a90bfa057dfcdbc55a347f5da677c506b53dd099cfec9d"
|
checksum = "07ef1a404ae479dd6906f4fa2c88b3c94028f1284beb42a47c183a7c27ee9a3e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ttf-parser 0.15.0",
|
"ttf-parser 0.15.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1995,18 +2080,18 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.0.10"
|
version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
|
checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-internal",
|
"pin-project-internal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-internal"
|
name = "pin-project-internal"
|
||||||
version = "1.0.10"
|
version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
|
checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2040,7 +2125,7 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"deflate 1.0.0",
|
"deflate 1.0.0",
|
||||||
"miniz_oxide 0.5.1",
|
"miniz_oxide 0.5.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2094,18 +2179,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.38"
|
version = "1.0.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
|
checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pulldown-cmark"
|
name = "pulldown-cmark"
|
||||||
version = "0.9.1"
|
version = "0.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
|
checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -2113,10 +2198,16 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quick-error"
|
||||||
version = "1.0.18"
|
version = "1.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -2196,9 +2287,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.13"
|
version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
|
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
@ -2216,18 +2307,20 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.5"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
|
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.25"
|
version = "0.6.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "remove_dir_all"
|
name = "remove_dir_all"
|
||||||
|
@ -2331,9 +2424,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.9"
|
version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd"
|
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -2346,18 +2439,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.137"
|
version = "1.0.140"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.137"
|
version = "1.0.140"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
|
checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2366,9 +2459,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.81"
|
version = "1.0.82"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
|
checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -2402,9 +2495,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.1.0"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sid"
|
name = "sid"
|
||||||
|
@ -2443,9 +2536,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.8.0"
|
version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smart-default"
|
name = "smart-default"
|
||||||
|
@ -2479,9 +2572,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.9.3"
|
version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d"
|
checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lock_api",
|
"lock_api",
|
||||||
]
|
]
|
||||||
|
@ -2593,13 +2686,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.94"
|
version = "1.0.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a"
|
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"unicode-xid",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2616,6 +2709,15 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
|
@ -2667,9 +2769,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiff"
|
name = "tiff"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7cfada0986f446a770eca461e8c6566cb879682f7d687c8348aa0c857bd52286"
|
checksum = "7259662e32d1e219321eb309d5f9d898b779769d81b76e762c07c8e5d38fcb65"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"flate2",
|
"flate2",
|
||||||
"jpeg-decoder 0.2.6",
|
"jpeg-decoder 0.2.6",
|
||||||
|
@ -2708,9 +2810,9 @@ checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ttf-parser"
|
name = "ttf-parser"
|
||||||
version = "0.15.0"
|
version = "0.15.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c74c96594835e10fa545e2a51e8709f30b173a092bfd6036ef2cec53376244f3"
|
checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "twox-hash"
|
name = "twox-hash"
|
||||||
|
@ -2732,6 +2834,12 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
|
@ -2744,12 +2852,6 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
@ -2781,15 +2883,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.10.2+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.80"
|
version = "0.2.82"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad"
|
checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
|
@ -2797,13 +2899,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.80"
|
version = "0.2.82"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4"
|
checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"lazy_static",
|
|
||||||
"log",
|
"log",
|
||||||
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
@ -2812,9 +2914,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.80"
|
version = "0.2.82"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5"
|
checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
|
@ -2822,9 +2924,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.80"
|
version = "0.2.82"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b"
|
checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2835,9 +2937,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.80"
|
version = "0.2.82"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
|
checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-client"
|
name = "wayland-client"
|
||||||
|
@ -2924,9 +3026,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.57"
|
version = "0.3.59"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283"
|
checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
@ -2934,9 +3036,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "weezl"
|
name = "weezl"
|
||||||
version = "0.1.6"
|
version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4"
|
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "3.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
|
@ -3018,7 +3129,7 @@ version = "0.3.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
|
checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nom",
|
"nom 7.1.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mpd_info_screen"
|
name = "mpd_info_screen"
|
||||||
version = "0.2.20"
|
version = "0.3.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Displays info on currently playing music from an MPD daemon"
|
description = "Displays info on currently playing music from an MPD daemon"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
@ -12,3 +12,10 @@ repository = "https://github.com/Stephen-Seo/mpd_info_screen"
|
||||||
structopt = "0.3"
|
structopt = "0.3"
|
||||||
image = "0.24"
|
image = "0.24"
|
||||||
ggez = "0.7"
|
ggez = "0.7"
|
||||||
|
freetype = { version = "0.7", optional = true }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
bindgen = { version = "0.53", optional = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
unicode_support = ["dep:freetype", "dep:bindgen"]
|
||||||
|
|
21
README.md
21
README.md
|
@ -11,9 +11,17 @@ A Rust program that displays info about the currently running MPD server.
|
||||||
The window shows albumart (may be embedded in the audio file, or is a "cover.jpg" in the same directory as the song file), a "time-remaining"
|
The window shows albumart (may be embedded in the audio file, or is a "cover.jpg" in the same directory as the song file), a "time-remaining"
|
||||||
counter, and the filename currently being played
|
counter, and the filename currently being played
|
||||||
|
|
||||||
|
By default, unicode characters will not display properly. Build the project with
|
||||||
|
the `unicode_support` feature enabled to enable fetching fonts from the local
|
||||||
|
filesystem to display unicode characters properly (if the system is missing a
|
||||||
|
font, then it will still be displayed incorrectly).
|
||||||
|
|
||||||
|
cargo build --release --features unicode_support
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
mpd_info_screen 0.2.20
|
|
||||||
|
mpd_info_screen 0.3.0
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
mpd_info_screen [FLAGS] [OPTIONS] <host> [port]
|
mpd_info_screen [FLAGS] [OPTIONS] <host> [port]
|
||||||
|
@ -42,7 +50,7 @@ Also note that pressing the H key while displaying text will hide the text.
|
||||||
|
|
||||||
# Issues / TODO
|
# Issues / TODO
|
||||||
|
|
||||||
- [ ] UTF-8 Non-ascii font support
|
- [x] UTF-8 Non-ascii font support (Use the `unicode_support` feature to enable; only tested in linux)
|
||||||
- [x] Support for album art not embedded but in the same directory
|
- [x] Support for album art not embedded but in the same directory
|
||||||
|
|
||||||
## MPD Version
|
## MPD Version
|
||||||
|
@ -64,3 +72,12 @@ MIT license.
|
||||||
|
|
||||||
Uses dependency [structopt](https://crates.io/crates/structopt) which is
|
Uses dependency [structopt](https://crates.io/crates/structopt) which is
|
||||||
licensed under Apache-2.0 or MIT licenses.
|
licensed under Apache-2.0 or MIT licenses.
|
||||||
|
|
||||||
|
## Unicode Support Dependencies
|
||||||
|
|
||||||
|
Uses dependency
|
||||||
|
[fontconfig](https://www.freedesktop.org/wiki/Software/fontconfig/) which is
|
||||||
|
[licensed with this license](https://www.freedesktop.org/software/fontconfig/fontconfig-devel/ln12.html).
|
||||||
|
|
||||||
|
Uses dependency [freetype](https://freetype.org) which is
|
||||||
|
[licensed with this license](https://freetype.org/license.html).
|
||||||
|
|
25
build.rs
Normal file
25
build.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#[cfg(feature = "unicode_support")]
|
||||||
|
use bindgen;
|
||||||
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "unicode_support"))]
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
#[cfg(feature = "unicode_support")]
|
||||||
|
fn main() {
|
||||||
|
println!("cargo:rustc-link-search=/usr/lib");
|
||||||
|
println!("cargo:rustc-link-lib=fontconfig");
|
||||||
|
println!("cargo:rerun-if-changed=src/bindgen_wrapper.h");
|
||||||
|
|
||||||
|
let bindings = bindgen::Builder::default()
|
||||||
|
.header("src/bindgen_wrapper.h")
|
||||||
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
||||||
|
.generate()
|
||||||
|
.expect("Unable to generate bindings");
|
||||||
|
|
||||||
|
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||||
|
bindings
|
||||||
|
.write_to_file(out_path.join("unicode_support_bindings.rs"))
|
||||||
|
.expect("Couldn't write bindings");
|
||||||
|
}
|
1
src/bindgen_wrapper.h
Normal file
1
src/bindgen_wrapper.h
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include <fontconfig/fontconfig.h>
|
179
src/display.rs
179
src/display.rs
|
@ -9,6 +9,7 @@ use ggez::graphics::{
|
||||||
use ggez::{timer, Context, GameError, GameResult};
|
use ggez::{timer, Context, GameError, GameResult};
|
||||||
use image::io::Reader as ImageReader;
|
use image::io::Reader as ImageReader;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::{atomic::Ordering, Arc, RwLockReadGuard};
|
use std::sync::{atomic::Ordering, Arc, RwLockReadGuard};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
@ -49,6 +50,125 @@ fn seconds_to_time(seconds: f64) -> String {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "unicode_support"))]
|
||||||
|
fn string_to_text(
|
||||||
|
string: String,
|
||||||
|
loaded_fonts: &mut Vec<(PathBuf, Font)>,
|
||||||
|
ctx: &mut Context,
|
||||||
|
) -> Text {
|
||||||
|
Text::new(TextFragment::from(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unicode_support")]
|
||||||
|
fn string_to_text(
|
||||||
|
string: String,
|
||||||
|
loaded_fonts: &mut Vec<(PathBuf, Font)>,
|
||||||
|
ctx: &mut Context,
|
||||||
|
) -> Text {
|
||||||
|
use super::unicode_support;
|
||||||
|
|
||||||
|
let mut text = Text::default();
|
||||||
|
let mut current_fragment = TextFragment::default();
|
||||||
|
|
||||||
|
if string.is_ascii() {
|
||||||
|
current_fragment.text = string;
|
||||||
|
text.add(current_fragment);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
let find_font =
|
||||||
|
|c: char, loaded_fonts: &mut Vec<(PathBuf, Font)>, ctx: &mut Context| -> Option<usize> {
|
||||||
|
for (idx, (path, _)) in loaded_fonts.iter().enumerate() {
|
||||||
|
let result = unicode_support::font_has_char(c, path);
|
||||||
|
if result.is_ok() && result.unwrap() {
|
||||||
|
return Some(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let find_result = unicode_support::get_matching_font_from_char(c);
|
||||||
|
if let Ok(path) = find_result {
|
||||||
|
let new_font = Font::new(ctx, &path);
|
||||||
|
if let Ok(font) = new_font {
|
||||||
|
loaded_fonts.push((path, font));
|
||||||
|
return Some(loaded_fonts.len() - 1);
|
||||||
|
} else {
|
||||||
|
println!("Failed to load {:?}: {:?}", &path, new_font);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("Failed to find font for {}", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut prev_is_ascii = true;
|
||||||
|
for c in string.chars() {
|
||||||
|
if c.is_ascii() {
|
||||||
|
if prev_is_ascii {
|
||||||
|
current_fragment.text.push(c);
|
||||||
|
} else {
|
||||||
|
if !current_fragment.text.is_empty() {
|
||||||
|
text.add(current_fragment);
|
||||||
|
current_fragment = Default::default();
|
||||||
|
}
|
||||||
|
current_fragment.text.push(c);
|
||||||
|
}
|
||||||
|
prev_is_ascii = true;
|
||||||
|
} else {
|
||||||
|
let idx_opt = find_font(c, loaded_fonts, ctx);
|
||||||
|
if prev_is_ascii {
|
||||||
|
if let Some(idx) = idx_opt {
|
||||||
|
if !current_fragment.text.is_empty() {
|
||||||
|
text.add(current_fragment);
|
||||||
|
current_fragment = Default::default();
|
||||||
|
}
|
||||||
|
let (_, font) = loaded_fonts[idx];
|
||||||
|
current_fragment.font = Some(font);
|
||||||
|
}
|
||||||
|
current_fragment.text.push(c);
|
||||||
|
} else {
|
||||||
|
if let Some(idx) = idx_opt {
|
||||||
|
let font = loaded_fonts[idx].1;
|
||||||
|
if let Some(current_font) = current_fragment.font {
|
||||||
|
if current_font == font {
|
||||||
|
current_fragment.text.push(c);
|
||||||
|
} else {
|
||||||
|
if !current_fragment.text.is_empty() {
|
||||||
|
text.add(current_fragment);
|
||||||
|
current_fragment = Default::default();
|
||||||
|
}
|
||||||
|
current_fragment.text.push(c);
|
||||||
|
current_fragment.font = Some(font);
|
||||||
|
}
|
||||||
|
} else if current_fragment.text.is_empty() {
|
||||||
|
current_fragment.text.push(c);
|
||||||
|
current_fragment.font = Some(font);
|
||||||
|
} else {
|
||||||
|
text.add(current_fragment);
|
||||||
|
current_fragment = Default::default();
|
||||||
|
|
||||||
|
current_fragment.text.push(c);
|
||||||
|
current_fragment.font = Some(font);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !current_fragment.text.is_empty() && current_fragment.font.is_some() {
|
||||||
|
text.add(current_fragment);
|
||||||
|
current_fragment = Default::default();
|
||||||
|
}
|
||||||
|
current_fragment.text.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev_is_ascii = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !current_fragment.text.is_empty() {
|
||||||
|
text.add(current_fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
text
|
||||||
|
}
|
||||||
|
|
||||||
pub struct MPDDisplay {
|
pub struct MPDDisplay {
|
||||||
opts: Opt,
|
opts: Opt,
|
||||||
mpd_handler: Result<MPDHandler, String>,
|
mpd_handler: Result<MPDHandler, String>,
|
||||||
|
@ -63,10 +183,13 @@ pub struct MPDDisplay {
|
||||||
album_art: Option<Image>,
|
album_art: Option<Image>,
|
||||||
album_art_draw_transform: Option<Transform>,
|
album_art_draw_transform: Option<Transform>,
|
||||||
filename_text: Text,
|
filename_text: Text,
|
||||||
|
filename_string_cache: String,
|
||||||
filename_transform: Transform,
|
filename_transform: Transform,
|
||||||
artist_text: Text,
|
artist_text: Text,
|
||||||
|
artist_string_cache: String,
|
||||||
artist_transform: Transform,
|
artist_transform: Transform,
|
||||||
title_text: Text,
|
title_text: Text,
|
||||||
|
title_string_cache: String,
|
||||||
title_transform: Transform,
|
title_transform: Transform,
|
||||||
timer_text: Text,
|
timer_text: Text,
|
||||||
timer_transform: Transform,
|
timer_transform: Transform,
|
||||||
|
@ -78,6 +201,7 @@ pub struct MPDDisplay {
|
||||||
hide_text: bool,
|
hide_text: bool,
|
||||||
tried_album_art_in_dir: bool,
|
tried_album_art_in_dir: bool,
|
||||||
mpd_play_state: MPDPlayState,
|
mpd_play_state: MPDPlayState,
|
||||||
|
loaded_fonts: Vec<(PathBuf, Font)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MPDDisplay {
|
impl MPDDisplay {
|
||||||
|
@ -111,6 +235,10 @@ impl MPDDisplay {
|
||||||
hide_text: false,
|
hide_text: false,
|
||||||
tried_album_art_in_dir: false,
|
tried_album_art_in_dir: false,
|
||||||
mpd_play_state: MPDPlayState::Playing,
|
mpd_play_state: MPDPlayState::Playing,
|
||||||
|
loaded_fonts: Vec::new(),
|
||||||
|
filename_string_cache: String::new(),
|
||||||
|
artist_string_cache: String::new(),
|
||||||
|
title_string_cache: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,13 +442,12 @@ impl MPDDisplay {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
text.set_font(
|
for fragment in text.fragments_mut() {
|
||||||
Font::default(),
|
fragment.scale = Some(PxScale {
|
||||||
PxScale {
|
|
||||||
x: current_x,
|
x: current_x,
|
||||||
y: current_y,
|
y: current_y,
|
||||||
},
|
});
|
||||||
);
|
}
|
||||||
width = text.width(ctx);
|
width = text.width(ctx);
|
||||||
height = text.height(ctx);
|
height = text.height(ctx);
|
||||||
|
|
||||||
|
@ -346,13 +473,12 @@ impl MPDDisplay {
|
||||||
} else {
|
} else {
|
||||||
let diff_scale_y = current_y / height * timer_height;
|
let diff_scale_y = current_y / height * timer_height;
|
||||||
let current_x = current_x * diff_scale_y / current_y;
|
let current_x = current_x * diff_scale_y / current_y;
|
||||||
text.set_font(
|
for fragment in text.fragments_mut() {
|
||||||
Font::default(),
|
fragment.scale = Some(PxScale {
|
||||||
PxScale {
|
|
||||||
x: current_x,
|
x: current_x,
|
||||||
y: diff_scale_y,
|
y: diff_scale_y,
|
||||||
},
|
});
|
||||||
);
|
}
|
||||||
*timer_x = current_x;
|
*timer_x = current_x;
|
||||||
*timer_y = diff_scale_y;
|
*timer_y = diff_scale_y;
|
||||||
// width = text.width(ctx); // not really used after this
|
// width = text.width(ctx); // not really used after this
|
||||||
|
@ -600,7 +726,14 @@ impl EventHandler for MPDDisplay {
|
||||||
} else {
|
} else {
|
||||||
self.mpd_play_state = MPDPlayState::Playing;
|
self.mpd_play_state = MPDPlayState::Playing;
|
||||||
if !shared.title.is_empty() {
|
if !shared.title.is_empty() {
|
||||||
self.title_text = Text::new(shared.title.clone());
|
if shared.title != self.title_string_cache {
|
||||||
|
self.title_string_cache = shared.title.clone();
|
||||||
|
self.title_text = string_to_text(
|
||||||
|
shared.title.clone(),
|
||||||
|
&mut self.loaded_fonts,
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.dirty_flag
|
self.dirty_flag
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -608,7 +741,14 @@ impl EventHandler for MPDDisplay {
|
||||||
.store(true, Ordering::Relaxed);
|
.store(true, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
if !shared.artist.is_empty() {
|
if !shared.artist.is_empty() {
|
||||||
self.artist_text = Text::new(shared.artist.clone());
|
if shared.artist != self.artist_string_cache {
|
||||||
|
self.artist_string_cache = shared.artist.clone();
|
||||||
|
self.artist_text = string_to_text(
|
||||||
|
shared.artist.clone(),
|
||||||
|
&mut self.loaded_fonts,
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.dirty_flag
|
self.dirty_flag
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -616,11 +756,18 @@ impl EventHandler for MPDDisplay {
|
||||||
.store(true, Ordering::Relaxed);
|
.store(true, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
if !shared.filename.is_empty() {
|
if !shared.filename.is_empty() {
|
||||||
if self.filename_text.contents() != shared.filename {
|
if shared.filename != self.filename_string_cache {
|
||||||
self.album_art = None;
|
self.filename_string_cache = shared.filename.clone();
|
||||||
self.tried_album_art_in_dir = false;
|
if self.filename_text.contents() != shared.filename {
|
||||||
|
self.album_art = None;
|
||||||
|
self.tried_album_art_in_dir = false;
|
||||||
|
}
|
||||||
|
self.filename_text = string_to_text(
|
||||||
|
shared.filename.clone(),
|
||||||
|
&mut self.loaded_fonts,
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
self.filename_text = Text::new(shared.filename.clone());
|
|
||||||
} else {
|
} else {
|
||||||
self.dirty_flag
|
self.dirty_flag
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
mod debug_log;
|
mod debug_log;
|
||||||
mod display;
|
mod display;
|
||||||
mod mpd_handler;
|
mod mpd_handler;
|
||||||
|
#[cfg(feature = "unicode_support")]
|
||||||
|
mod unicode_support;
|
||||||
|
|
||||||
use ggez::conf::{WindowMode, WindowSetup};
|
use ggez::conf::{WindowMode, WindowSetup};
|
||||||
use ggez::event::winit_event::{ElementState, KeyboardInput, ModifiersState};
|
use ggez::event::winit_event::{ElementState, KeyboardInput, ModifiersState};
|
||||||
use ggez::event::{self, ControlFlow, EventHandler};
|
use ggez::event::{self, ControlFlow, EventHandler};
|
||||||
|
use ggez::filesystem::mount;
|
||||||
use ggez::graphics::{self, Rect};
|
use ggez::graphics::{self, Rect};
|
||||||
use ggez::{ContextBuilder, GameError};
|
use ggez::{ContextBuilder, GameError};
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
@ -61,6 +65,9 @@ fn main() -> Result<(), String> {
|
||||||
.build()
|
.build()
|
||||||
.expect("Failed to create ggez context");
|
.expect("Failed to create ggez context");
|
||||||
|
|
||||||
|
// mount "/" read-only so that fonts can be loaded via absolute paths
|
||||||
|
mount(&mut ctx, &PathBuf::from("/"), true);
|
||||||
|
|
||||||
let mut display = display::MPDDisplay::new(&mut ctx, opt.clone());
|
let mut display = display::MPDDisplay::new(&mut ctx, opt.clone());
|
||||||
|
|
||||||
let mut modifiers_state: ModifiersState = ModifiersState::default();
|
let mut modifiers_state: ModifiersState = ModifiersState::default();
|
||||||
|
|
5
src/unicode_support.rs
Normal file
5
src/unicode_support.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
mod fontconfig;
|
||||||
|
mod freetype;
|
||||||
|
|
||||||
|
pub use self::freetype::font_has_char;
|
||||||
|
pub use fontconfig::{get_matching_font_from_char, get_matching_font_from_str};
|
348
src/unicode_support/fontconfig.rs
Normal file
348
src/unicode_support/fontconfig.rs
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
use std::{path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
|
mod ffi {
|
||||||
|
use std::{ffi::CStr, os::raw::c_int};
|
||||||
|
|
||||||
|
mod bindgen {
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
#![allow(deref_nullptr)]
|
||||||
|
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/unicode_support_bindings.rs"));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FcConfigWr {
|
||||||
|
config: *mut bindgen::FcConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for FcConfigWr {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !self.config.is_null() {
|
||||||
|
unsafe {
|
||||||
|
bindgen::FcConfigDestroy(self.config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FcConfigWr {
|
||||||
|
pub fn new() -> Result<Self, String> {
|
||||||
|
let config = unsafe { bindgen::FcInitLoadConfigAndFonts() };
|
||||||
|
if config.is_null() {
|
||||||
|
Err(String::from("Failed to create FcConfig"))
|
||||||
|
} else {
|
||||||
|
Ok(Self { config })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&mut self) -> *mut bindgen::FcConfig {
|
||||||
|
self.config
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_pattern_to_config(&mut self, pattern: &mut FcPatternWr) -> bool {
|
||||||
|
unsafe {
|
||||||
|
bindgen::FcConfigSubstitute(
|
||||||
|
self.config,
|
||||||
|
pattern.get(),
|
||||||
|
bindgen::_FcMatchKind_FcMatchPattern,
|
||||||
|
) == bindgen::FcTrue as bindgen::FcBool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn font_match(&mut self, pattern: &mut FcPatternWr) -> Result<FcPatternWr, String> {
|
||||||
|
unsafe {
|
||||||
|
let mut result: bindgen::FcResult = 0 as bindgen::FcResult;
|
||||||
|
let result_pattern = bindgen::FcFontMatch(
|
||||||
|
self.config,
|
||||||
|
pattern.get(),
|
||||||
|
&mut result as *mut bindgen::FcResult,
|
||||||
|
);
|
||||||
|
if result != bindgen::_FcResult_FcResultMatch {
|
||||||
|
if !result_pattern.is_null() {
|
||||||
|
bindgen::FcPatternDestroy(result_pattern);
|
||||||
|
return Err(String::from("Failed to FcFontMatch (FcResult is not FcResultMatch; result_pattern is not null)"));
|
||||||
|
} else {
|
||||||
|
return Err(format!(
|
||||||
|
"Failed to FcFontMatch (FcResult is not FcResultMatch; {:?})",
|
||||||
|
result
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else if result_pattern.is_null() {
|
||||||
|
return Err(String::from(
|
||||||
|
"Failed to FcFontMatch (result_pattern is null)",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(FcPatternWr {
|
||||||
|
pattern: result_pattern,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FcCharSetWr {
|
||||||
|
charset: *mut bindgen::FcCharSet,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for FcCharSetWr {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !self.charset.is_null() {
|
||||||
|
unsafe {
|
||||||
|
bindgen::FcCharSetDestroy(self.charset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FcCharSetWr {
|
||||||
|
pub fn new_with_str(s: &str) -> Result<Self, String> {
|
||||||
|
let charset;
|
||||||
|
unsafe {
|
||||||
|
let charset_ptr = bindgen::FcCharSetCreate();
|
||||||
|
if charset_ptr.is_null() {
|
||||||
|
return Err(String::from("Failed to create FcCharSet with str"));
|
||||||
|
}
|
||||||
|
charset = FcCharSetWr {
|
||||||
|
charset: charset_ptr,
|
||||||
|
};
|
||||||
|
for c in s.chars() {
|
||||||
|
if bindgen::FcCharSetAddChar(charset.charset, c as u32)
|
||||||
|
== bindgen::FcFalse as bindgen::FcBool
|
||||||
|
{
|
||||||
|
return Err(String::from("Failed to add chars from str into FcCharSet"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(charset)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_char(c: char) -> Result<Self, String> {
|
||||||
|
let charset;
|
||||||
|
unsafe {
|
||||||
|
let charset_ptr = bindgen::FcCharSetCreate();
|
||||||
|
if charset_ptr.is_null() {
|
||||||
|
return Err(String::from("Failed to create FcCharSet with char"));
|
||||||
|
}
|
||||||
|
charset = FcCharSetWr {
|
||||||
|
charset: charset_ptr,
|
||||||
|
};
|
||||||
|
if bindgen::FcCharSetAddChar(charset.charset, c as u32)
|
||||||
|
== bindgen::FcFalse as bindgen::FcBool
|
||||||
|
{
|
||||||
|
return Err(String::from("Failed to add char to FcCharSet"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(charset)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&mut self) -> *mut bindgen::FcCharSet {
|
||||||
|
self.charset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FcPatternWr {
|
||||||
|
pattern: *mut bindgen::FcPattern,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for FcPatternWr {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !self.pattern.is_null() {
|
||||||
|
unsafe {
|
||||||
|
bindgen::FcPatternDestroy(self.pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FcPatternWr {
|
||||||
|
pub fn new_with_charset(c: &mut FcCharSetWr) -> Result<Self, String> {
|
||||||
|
let pattern;
|
||||||
|
unsafe {
|
||||||
|
let pattern_ptr = bindgen::FcPatternCreate();
|
||||||
|
if pattern_ptr.is_null() {
|
||||||
|
return Err(String::from("Failed to FcPatternCreate"));
|
||||||
|
}
|
||||||
|
pattern = Self {
|
||||||
|
pattern: pattern_ptr,
|
||||||
|
};
|
||||||
|
bindgen::FcDefaultSubstitute(pattern.pattern);
|
||||||
|
|
||||||
|
let value = bindgen::FcValue {
|
||||||
|
type_: bindgen::_FcType_FcTypeCharSet,
|
||||||
|
u: bindgen::_FcValue__bindgen_ty_1 { c: c.get() },
|
||||||
|
};
|
||||||
|
|
||||||
|
if bindgen::FcPatternAdd(
|
||||||
|
pattern.pattern,
|
||||||
|
bindgen::FC_CHARSET as *const _ as *const i8,
|
||||||
|
value,
|
||||||
|
bindgen::FcTrue as bindgen::FcBool,
|
||||||
|
) == bindgen::FcFalse as bindgen::FcBool
|
||||||
|
{
|
||||||
|
return Err(String::from("Failed to add FcCharSet to new Pattern"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&mut self) -> *mut bindgen::FcPattern {
|
||||||
|
self.pattern
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_count(&self) -> c_int {
|
||||||
|
unsafe { bindgen::FcPatternObjectCount(self.pattern) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn filter_to_filenames(&self) -> Result<Self, String> {
|
||||||
|
let pattern;
|
||||||
|
unsafe {
|
||||||
|
let mut file_object_set_filter = FcObjectSetWr::new_file_object_set()?;
|
||||||
|
let pattern_ptr =
|
||||||
|
bindgen::FcPatternFilter(self.pattern, file_object_set_filter.get());
|
||||||
|
if pattern_ptr.is_null() {
|
||||||
|
return Err(String::from("Failed to FcPatternFilter"));
|
||||||
|
}
|
||||||
|
pattern = Self {
|
||||||
|
pattern: pattern_ptr,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_filename_contents(&self) -> Result<Vec<String>, String> {
|
||||||
|
let mut vec: Vec<String> = Vec::new();
|
||||||
|
let count = self.get_count();
|
||||||
|
unsafe {
|
||||||
|
let mut value = bindgen::FcValue {
|
||||||
|
type_: 0,
|
||||||
|
u: bindgen::_FcValue__bindgen_ty_1 { i: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
for i in 0..count {
|
||||||
|
if bindgen::FcPatternGet(
|
||||||
|
self.pattern,
|
||||||
|
bindgen::FC_FILE as *const _ as *const i8,
|
||||||
|
i,
|
||||||
|
&mut value as *mut bindgen::FcValue,
|
||||||
|
) == bindgen::_FcResult_FcResultMatch
|
||||||
|
{
|
||||||
|
if value.type_ == bindgen::_FcType_FcTypeString {
|
||||||
|
let cs = CStr::from_ptr(value.u.s as *const i8);
|
||||||
|
vec.push(
|
||||||
|
cs.to_str()
|
||||||
|
.map_err(|_| String::from("Failed to convert CStr to String"))?
|
||||||
|
.to_owned(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(vec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FcObjectSetWr {
|
||||||
|
object_set: *mut bindgen::FcObjectSet,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for FcObjectSetWr {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
if !self.object_set.is_null() {
|
||||||
|
bindgen::FcObjectSetDestroy(self.object_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FcObjectSetWr {
|
||||||
|
pub fn new_file_object_set() -> Result<Self, String> {
|
||||||
|
let object_set;
|
||||||
|
unsafe {
|
||||||
|
let object_set_ptr = bindgen::FcObjectSetCreate();
|
||||||
|
if object_set_ptr.is_null() {
|
||||||
|
return Err(String::from("Failed to FcObjectSetCreate"));
|
||||||
|
}
|
||||||
|
|
||||||
|
object_set = Self {
|
||||||
|
object_set: object_set_ptr,
|
||||||
|
};
|
||||||
|
|
||||||
|
if bindgen::FcObjectSetAdd(
|
||||||
|
object_set.object_set,
|
||||||
|
bindgen::FC_FILE as *const _ as *const i8,
|
||||||
|
) == bindgen::FcFalse as bindgen::FcBool
|
||||||
|
{
|
||||||
|
return Err(String::from(
|
||||||
|
"Failed to add \"FC_FILE\" with FcObjectSetAdd",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(object_set)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&mut self) -> *mut bindgen::FcObjectSet {
|
||||||
|
self.object_set
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_matching_font_from_str(s: &str) -> Result<PathBuf, String> {
|
||||||
|
let mut config = ffi::FcConfigWr::new()?;
|
||||||
|
let mut charset = ffi::FcCharSetWr::new_with_str(s)?;
|
||||||
|
let mut search_pattern = ffi::FcPatternWr::new_with_charset(&mut charset)?;
|
||||||
|
if !config.apply_pattern_to_config(&mut search_pattern) {
|
||||||
|
return Err(String::from("Failed to apply_pattern_to_config"));
|
||||||
|
}
|
||||||
|
let result_pattern = config.font_match(&mut search_pattern)?;
|
||||||
|
let filtered_pattern = result_pattern.filter_to_filenames()?;
|
||||||
|
let result_vec = filtered_pattern.get_filename_contents()?;
|
||||||
|
|
||||||
|
if result_vec.is_empty() {
|
||||||
|
Err(String::from(
|
||||||
|
"Empty result_vec for get_matching_font_from_str",
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
PathBuf::from_str(&result_vec[0]).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_matching_font_from_char(c: char) -> Result<PathBuf, String> {
|
||||||
|
let mut config = ffi::FcConfigWr::new()?;
|
||||||
|
let mut charset = ffi::FcCharSetWr::new_with_char(c)?;
|
||||||
|
let mut search_pattern = ffi::FcPatternWr::new_with_charset(&mut charset)?;
|
||||||
|
if !config.apply_pattern_to_config(&mut search_pattern) {
|
||||||
|
return Err(String::from("Failed to apply_pattern_to_config"));
|
||||||
|
}
|
||||||
|
let result_pattern = config.font_match(&mut search_pattern)?;
|
||||||
|
let filtered_pattern = result_pattern.filter_to_filenames()?;
|
||||||
|
let result_vec = filtered_pattern.get_filename_contents()?;
|
||||||
|
|
||||||
|
if result_vec.is_empty() {
|
||||||
|
Err(String::from(
|
||||||
|
"Empty result_vec for get_matching_font_from_char",
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
PathBuf::from_str(&result_vec[0]).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ascii_fetching() {
|
||||||
|
let fetched_path =
|
||||||
|
get_matching_font_from_char('a').expect("Should be able to find match for 'a'");
|
||||||
|
println!("{:?}", fetched_path);
|
||||||
|
}
|
||||||
|
}
|
157
src/unicode_support/freetype.rs
Normal file
157
src/unicode_support/freetype.rs
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
mod ffi {
|
||||||
|
use freetype::freetype::{
|
||||||
|
FT_Done_Face, FT_Done_Library, FT_Face, FT_FaceRec_, FT_Get_Char_Index, FT_Init_FreeType,
|
||||||
|
FT_Library, FT_ModuleRec_, FT_Open_Args, FT_Open_Face, FT_Parameter_, FT_StreamRec_,
|
||||||
|
FT_OPEN_PATHNAME,
|
||||||
|
};
|
||||||
|
use std::ffi::CString;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub struct FTLibrary {
|
||||||
|
library: FT_Library,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for FTLibrary {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !self.library.is_null() {
|
||||||
|
unsafe {
|
||||||
|
FT_Done_Library(self.library);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FTLibrary {
|
||||||
|
pub fn new() -> Option<FTLibrary> {
|
||||||
|
unsafe {
|
||||||
|
let mut library_ptr: FT_Library = 0 as FT_Library;
|
||||||
|
if FT_Init_FreeType(&mut library_ptr) != 0 {
|
||||||
|
Some(FTLibrary {
|
||||||
|
library: library_ptr,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self) -> FT_Library {
|
||||||
|
self.library
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FTOpenArgs {
|
||||||
|
args: FT_Open_Args,
|
||||||
|
pathname: Option<CString>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FTOpenArgs {
|
||||||
|
pub fn new_with_path(path: &Path) -> Self {
|
||||||
|
unsafe {
|
||||||
|
let cstring: CString = CString::from_vec_unchecked(
|
||||||
|
path.as_os_str().to_str().unwrap().as_bytes().to_vec(),
|
||||||
|
);
|
||||||
|
let args = FT_Open_Args {
|
||||||
|
flags: FT_OPEN_PATHNAME,
|
||||||
|
memory_base: 0 as *const u8,
|
||||||
|
memory_size: 0,
|
||||||
|
pathname: cstring.as_ptr() as *mut i8,
|
||||||
|
stream: 0 as *mut FT_StreamRec_,
|
||||||
|
driver: 0 as *mut FT_ModuleRec_,
|
||||||
|
num_params: 0,
|
||||||
|
params: 0 as *mut FT_Parameter_,
|
||||||
|
};
|
||||||
|
|
||||||
|
FTOpenArgs {
|
||||||
|
args,
|
||||||
|
pathname: Some(cstring),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_args(&self) -> FT_Open_Args {
|
||||||
|
self.args
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_ptr(&mut self) -> *mut FT_Open_Args {
|
||||||
|
&mut self.args as *mut FT_Open_Args
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FTFaces {
|
||||||
|
faces: Vec<FT_Face>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for FTFaces {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
for face in &self.faces {
|
||||||
|
unsafe {
|
||||||
|
FT_Done_Face(*face);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FTFaces {
|
||||||
|
pub fn new(library: &FTLibrary, args: &mut FTOpenArgs) -> Result<FTFaces, ()> {
|
||||||
|
let mut faces = FTFaces { faces: Vec::new() };
|
||||||
|
unsafe {
|
||||||
|
let count;
|
||||||
|
let mut face: FT_Face = 0 as FT_Face;
|
||||||
|
// first get number of faces
|
||||||
|
let mut result = FT_Open_Face(
|
||||||
|
library.get(),
|
||||||
|
args.get_ptr(),
|
||||||
|
-1,
|
||||||
|
&mut face as *mut *mut FT_FaceRec_,
|
||||||
|
);
|
||||||
|
if result != 0 {
|
||||||
|
FT_Done_Face(face);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
count = (*face).num_faces;
|
||||||
|
|
||||||
|
for i in 0..count {
|
||||||
|
result = FT_Open_Face(
|
||||||
|
library.get(),
|
||||||
|
args.get_ptr(),
|
||||||
|
i,
|
||||||
|
&mut face as *mut *mut FT_FaceRec_,
|
||||||
|
);
|
||||||
|
if result != 0 {
|
||||||
|
FT_Done_Face(face);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
faces.faces.push(face);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(faces)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_char(&self, c: char) -> bool {
|
||||||
|
let char_value: u64 = c as u64;
|
||||||
|
|
||||||
|
for face in &self.faces {
|
||||||
|
unsafe {
|
||||||
|
let result = FT_Get_Char_Index(*face, char_value);
|
||||||
|
if result != 0 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn font_has_char(c: char, font_path: &Path) -> Result<bool, ()> {
|
||||||
|
let library = ffi::FTLibrary::new().ok_or(())?;
|
||||||
|
let mut args = ffi::FTOpenArgs::new_with_path(font_path);
|
||||||
|
let faces = ffi::FTFaces::new(&library, &mut args)?;
|
||||||
|
|
||||||
|
Ok(faces.has_char(c))
|
||||||
|
}
|
Loading…
Reference in a new issue