Compare commits
19 Commits
d9d3438997
...
master
Author | SHA1 | Date | |
---|---|---|---|
a00eade3bb | |||
76512404e1 | |||
02c0f24cd4 | |||
881da90290 | |||
d63eb2b9d1 | |||
b7a1a6c07e | |||
9d8713f622 | |||
636aa14be3 | |||
59e1852f62 | |||
2f7e9853aa | |||
02120b3263 | |||
a7ea7bd6d7 | |||
ac261f0761 | |||
4053fa70f4 | |||
b5239e14b6 | |||
c8795588d8 | |||
7110054836 | |||
f7b9036063 | |||
c6c07e788b |
438
Cargo.lock
generated
438
Cargo.lock
generated
@ -4,84 +4,85 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.4"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
|
||||
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.4"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
|
||||
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.2"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
|
||||
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.0"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.1"
|
||||
version = "3.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
|
||||
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.75"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.18.3"
|
||||
version = "0.18.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f33613627f0dea6a731b0605101fad59ba4f193a52c96c4687728d822605a8a1"
|
||||
checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-sys-rs",
|
||||
@ -104,9 +105,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cfg-expr"
|
||||
version = "0.15.5"
|
||||
version = "0.15.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3"
|
||||
checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
@ -114,9 +115,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.6"
|
||||
version = "4.5.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
|
||||
checksum = "b95dca1b68188a08ca6af9d96a6576150f598824bdb528c1190460c2940a0b48"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@ -124,9 +125,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.4.6"
|
||||
version = "4.5.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
|
||||
checksum = "9ab52925392148efd3f7562f2136a81ffb778076bcc85727c6e020d6dd57cf15"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@ -136,33 +137,33 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.4.2"
|
||||
version = "4.5.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
|
||||
checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.5.1"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
|
||||
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.1"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
|
||||
checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
|
||||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
@ -177,16 +178,6 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "field-offset"
|
||||
version = "0.3.6"
|
||||
@ -199,24 +190,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.28"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
|
||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.28"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.28"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
|
||||
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@ -225,32 +216,32 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.28"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
|
||||
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.28"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.28"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
|
||||
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.28"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-macro",
|
||||
@ -262,9 +253,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gdk-pixbuf"
|
||||
version = "0.18.0"
|
||||
version = "0.18.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbc9c2ed73a81d556b65d08879ba4ee58808a6b1927ce915262185d6d547c6f3"
|
||||
checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec"
|
||||
dependencies = [
|
||||
"gdk-pixbuf-sys",
|
||||
"gio",
|
||||
@ -320,9 +311,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gio"
|
||||
version = "0.18.3"
|
||||
version = "0.18.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47d809baf02bdf1b5ef4ad3bf60dd9d4977149db4612b7bbb58e56aef168193b"
|
||||
checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -352,9 +343,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.18.3"
|
||||
version = "0.18.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58cf801b6f7829fa76db37449ab67c9c98a2b1bf21076d9113225621e61a0fa6"
|
||||
checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
@ -375,16 +366,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.18.3"
|
||||
version = "0.18.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72793962ceece3863c2965d7f10c8786323b17c7adea75a515809fa20ab799a5"
|
||||
checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-crate 2.0.0",
|
||||
"heck 0.4.1",
|
||||
"proc-macro-crate 2.0.2",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -518,9 +509,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.1"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
@ -529,10 +520,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.3"
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
@ -542,9 +539,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.0.1"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad227c3af19d4914570ad36d30409928b75967c298feb9ea1969db3a610bb14e"
|
||||
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@ -552,44 +549,44 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||
checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.150"
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.11"
|
||||
name = "libc"
|
||||
version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.3"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.0"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@ -608,19 +605,20 @@ dependencies = [
|
||||
"gtk4",
|
||||
"log",
|
||||
"poppler-rs",
|
||||
"strum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
version = "1.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.18.0"
|
||||
version = "0.18.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06a9e54b831d033206160096b825f2070cf5fda7e35167b1c01e9e774f9202d1"
|
||||
checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4"
|
||||
dependencies = [
|
||||
"gio",
|
||||
"glib",
|
||||
@ -643,9 +641,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
@ -655,9 +653,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.27"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||
|
||||
[[package]]
|
||||
name = "poppler-rs"
|
||||
@ -698,11 +696,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "2.0.0"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
|
||||
checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
|
||||
dependencies = [
|
||||
"toml_edit 0.20.7",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.20.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -731,27 +730,27 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.67"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
|
||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -761,9 +760,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -772,63 +771,56 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.25"
|
||||
name = "rustversion"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.19"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0"
|
||||
checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.188"
|
||||
version = "1.0.217"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
||||
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.188"
|
||||
version = "1.0.217"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.3"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
|
||||
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -844,15 +836,37 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.1"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.26.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
@ -867,9 +881,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.37"
|
||||
version = "2.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
|
||||
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -878,12 +892,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "system-deps"
|
||||
version = "6.1.1"
|
||||
version = "6.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3"
|
||||
checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
|
||||
dependencies = [
|
||||
"cfg-expr",
|
||||
"heck",
|
||||
"heck 0.5.0",
|
||||
"pkg-config",
|
||||
"toml",
|
||||
"version-compare",
|
||||
@ -891,56 +905,56 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.11"
|
||||
version = "0.12.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a"
|
||||
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.50"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.50"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.8"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
|
||||
checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.19.15",
|
||||
"toml_edit 0.20.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -950,6 +964,17 @@ name = "toml_edit"
|
||||
version = "0.19.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
@ -958,40 +983,29 @@ dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.20.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
|
||||
checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
@ -1011,11 +1025,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1026,22 +1040,32 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
@ -1050,51 +1074,57 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.15"
|
||||
version = "0.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
|
||||
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -14,3 +14,4 @@ gtk = { version = "0.7.3", package = "gtk4", features = ["v4_8"] }
|
||||
anyhow = "1.0.75"
|
||||
log = "0.4.20"
|
||||
env_logger = "0.10.1"
|
||||
strum = { version = "0.26.3", features = ["derive"] }
|
||||
|
14
de.frajul.music-reader.gschema.xml
Normal file
14
de.frajul.music-reader.gschema.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- GTK settings schema / configuration. Deploy this e.g. to $HOME/.local/share/glib-2.0/schemas -->
|
||||
<schemalist>
|
||||
<schema id="de.frajul.music-reader" path="/de/frajul/music-reader/">
|
||||
<key name="fullscreen" type="b">
|
||||
<default>false</default>
|
||||
<summary>Whether the application is in fullscreen mode</summary>
|
||||
</key>
|
||||
<key name="color-mode" type="s">
|
||||
<default>'Normal'</default>
|
||||
<summary>The color mode used to render the pdf pages</summary>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
62
flake.lock
generated
62
flake.lock
generated
@ -1,15 +1,33 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1698420672,
|
||||
"narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=",
|
||||
"lastModified": 1736429655,
|
||||
"narHash": "sha256-BwMekRuVlSB9C0QgwKMICiJ5EVbLGjfe4qyueyNQyGI=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "aeb58d5e8faead8980a807c840232697982d47b9",
|
||||
"rev": "0621e47bd95542b8e1ce2ee2d65d6a1f887a13ce",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -21,12 +39,10 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1704842529,
|
||||
"narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5",
|
||||
"type": "github"
|
||||
"lastModified": 0,
|
||||
"narHash": "sha256-DjkQPnkAfd7eB522PwnkGhOMuT9QVCZspDpJJYyOj60=",
|
||||
"path": "/nix/store/g3jyakqb3ipnr6gz5rw10fb17ckr2z00-source",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
@ -35,11 +51,11 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1704842529,
|
||||
"narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=",
|
||||
"lastModified": 1736241350,
|
||||
"narHash": "sha256-CHd7yhaDigUuJyDeX0SADbTM9FXfiWaeNyY34FL1wQU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5",
|
||||
"rev": "8c9fd3e564728e90829ee7dbac6edc972971cd0f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -51,9 +67,9 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"naersk": "naersk",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"utils": "utils"
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
@ -70,24 +86,6 @@
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1701680307,
|
||||
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
107
flake.nix
107
flake.nix
@ -1,41 +1,84 @@
|
||||
{
|
||||
inputs = {
|
||||
naersk.url = "github:nix-community/naersk/master";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
utils.url = "github:numtide/flake-utils";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
naersk.url = "github:nix-community/naersk/master";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, utils, naersk }:
|
||||
utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
naersk-lib = pkgs.callPackage naersk { };
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
naersk,
|
||||
}:
|
||||
let
|
||||
packageOutputs = flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
naersk-lib = pkgs.callPackage naersk { };
|
||||
|
||||
# Needed at compile time (on build system)
|
||||
nativeBuildInputs = with pkgs; [
|
||||
gtk4
|
||||
cairo
|
||||
glib
|
||||
pkg-config
|
||||
poppler
|
||||
wrapGAppsHook
|
||||
];
|
||||
# Needed at runtime (on run system)
|
||||
buildInputs = with pkgs; [ ];
|
||||
in rec {
|
||||
defaultPackage = naersk-lib.buildPackage {
|
||||
src = ./.;
|
||||
inherit buildInputs;
|
||||
inherit nativeBuildInputs;
|
||||
};
|
||||
devShell = with pkgs;
|
||||
mkShell {
|
||||
buildInputs =
|
||||
[ cargo rustc rustfmt pre-commit rustPackages.clippy ];
|
||||
# Without inheriting nativeBuildinputs, cargo build will fail but that is good since we want to use only nix build
|
||||
# inherit nativeBuildInputs;
|
||||
# Needed at compile time (on build system)
|
||||
nativeBuildInputs = with pkgs; [
|
||||
gtk4
|
||||
cairo
|
||||
glib
|
||||
pkg-config
|
||||
poppler
|
||||
wrapGAppsHook
|
||||
];
|
||||
# Needed at runtime (on run system)
|
||||
buildInputs = with pkgs; [ ];
|
||||
in
|
||||
rec {
|
||||
defaultPackage = naersk-lib.buildPackage {
|
||||
src = ./.;
|
||||
inherit buildInputs;
|
||||
inherit nativeBuildInputs;
|
||||
|
||||
RUST_SRC_PATH = rustPlatform.rustLibSrc;
|
||||
postInstall = ''
|
||||
mkdir -p $out/share/applications
|
||||
cp ${./music-reader.desktop} $out/share/applications/music-reader.desktop
|
||||
|
||||
mkdir -p $out/share/icons
|
||||
cp ${./music-reader.png} $out/share/icons/music-reader.png
|
||||
|
||||
mkdir -p $out/share/glib-2.0/schemas
|
||||
cp ${./de.frajul.music-reader.gschema.xml} $out/share/glib-2.0/schemas/de.frajul.music-reader.gschema.xml
|
||||
glib-compile-schemas $out/share/glib-2.0/schemas/
|
||||
'';
|
||||
};
|
||||
});
|
||||
devShell =
|
||||
with pkgs;
|
||||
mkShell {
|
||||
buildInputs = [
|
||||
cargo
|
||||
rustc
|
||||
rustfmt
|
||||
pre-commit
|
||||
rustPackages.clippy
|
||||
|
||||
gtk4
|
||||
cairo
|
||||
glib
|
||||
pkg-config
|
||||
poppler
|
||||
wrapGAppsHook
|
||||
];
|
||||
# Without inheriting nativeBuildinputs, cargo build will fail but that is good since we want to use only nix build
|
||||
# inherit nativeBuildInputs;
|
||||
|
||||
RUST_SRC_PATH = rustPlatform.rustLibSrc;
|
||||
};
|
||||
}
|
||||
);
|
||||
in
|
||||
packageOutputs
|
||||
// {
|
||||
hydraJobs = {
|
||||
x86_64-linux.music-reader = packageOutputs.defaultPackage.x86_64-linux;
|
||||
aarch64-linux.music-reader = packageOutputs.defaultPackage.aarch64-linux;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
9
music-reader.desktop
Normal file
9
music-reader.desktop
Normal file
@ -0,0 +1,9 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Name=Music Reader
|
||||
Icon=music-reader
|
||||
Categories=Viewer;Utility;
|
||||
Keywords=viewer;document;pdf;
|
||||
Exec=music-reader %F
|
||||
MimeType=application/pdf;
|
BIN
music-reader.png
Normal file
BIN
music-reader.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 488 KiB |
60
src/cache.rs
60
src/cache.rs
@ -1,4 +1,4 @@
|
||||
use crate::draw;
|
||||
use crate::{color_mode::{self, ColorMode}, draw};
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use glib::timeout_future;
|
||||
use gtk::{gdk::Texture, prelude::TextureExt};
|
||||
@ -19,15 +19,17 @@ pub struct PageCache {
|
||||
max_num_stored_pages: usize,
|
||||
pages: BTreeMap<usize, Rc<MyPageType>>,
|
||||
last_requested_page_number: PageNumber,
|
||||
color_mode: ColorMode,
|
||||
}
|
||||
|
||||
impl PageCache {
|
||||
pub fn new(document: Document, max_num_stored_pages: usize) -> Self {
|
||||
pub fn new(document: Document, max_num_stored_pages: usize, color_mode : ColorMode) -> Self {
|
||||
PageCache {
|
||||
document,
|
||||
max_num_stored_pages,
|
||||
pages: BTreeMap::new(),
|
||||
last_requested_page_number: 0,
|
||||
color_mode,
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,28 +51,30 @@ impl PageCache {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cache_page(&mut self, page_number: PageNumber, height: i32) -> Option<CacheResponse> {
|
||||
pub fn cache_page(&mut self, page_number: PageNumber, height: i32) -> Result<Option<CacheResponse>> {
|
||||
debug!("Caching page {}", page_number);
|
||||
if page_number.abs_diff(self.last_requested_page_number)
|
||||
> self.max_num_stored_pages.div_ceil(2)
|
||||
{
|
||||
debug!("Page too far from reader, aborting caching call");
|
||||
return None;
|
||||
bail!("Page too far from reader, aborting caching call");
|
||||
}
|
||||
|
||||
let begin_of_cashing = Instant::now();
|
||||
if let Some(page) = self.pages.get(&page_number) {
|
||||
if page.height() >= height {
|
||||
debug!("Page already in cache");
|
||||
return None;
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
if page_number >= self.document.n_pages() as usize {
|
||||
bail!("Requested page {} has too high number and is not in the document", page_number);
|
||||
}
|
||||
|
||||
let begin_of_cashing = Instant::now();
|
||||
let mut response = None;
|
||||
|
||||
println!("Getting page form poppler: {}", page_number);
|
||||
if let Some(page) = self.document.page(page_number as i32) {
|
||||
let pages = vec![Rc::new(page)];
|
||||
let texture = draw::draw_pages_to_texture(&pages, height);
|
||||
let texture = draw::draw_pages_to_texture(&pages, height, &self.color_mode);
|
||||
let page = Rc::new(texture);
|
||||
|
||||
// Overwrite page with lower resolution if exists
|
||||
@ -89,7 +93,7 @@ impl PageCache {
|
||||
page_number,
|
||||
begin_of_cashing.elapsed().as_millis()
|
||||
);
|
||||
response
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
fn remove_most_distant_page(&mut self) -> anyhow::Result<()> {
|
||||
@ -128,22 +132,24 @@ impl PageCache {
|
||||
fn process_command(&mut self, command: CacheCommand) -> Result<Option<CacheResponse>> {
|
||||
debug!("Processing command: {:?}...", command);
|
||||
match command {
|
||||
CacheCommand::Cache(command) => Ok(self.cache_page(command.page, command.height)),
|
||||
CacheCommand::Cache(command) => Ok(self.cache_page(command.page, command.height)?),
|
||||
CacheCommand::Retrieve(command) => match command {
|
||||
RetrievePagesCommand::GetCurrentTwoPages { page_left_number } => {
|
||||
let page_left = self.get_page_or_cache(page_left_number)?;
|
||||
if let Ok(page_right) = self.get_page_or_cache(page_left_number + 1) {
|
||||
Ok(Some(CacheResponse::TwoPagesRetrieved {
|
||||
page_number_left: page_left_number,
|
||||
page_left,
|
||||
page_number_right: page_left_number + 1,
|
||||
page_right,
|
||||
}))
|
||||
} else {
|
||||
Ok(Some(CacheResponse::SinglePageRetrieved { page: page_left }))
|
||||
Ok(Some(CacheResponse::SinglePageRetrieved { page_number: page_left_number, page: page_left }))
|
||||
}
|
||||
}
|
||||
RetrievePagesCommand::GetCurrentPage { page_number } => {
|
||||
let page = self.get_page_or_cache(page_number)?;
|
||||
Ok(Some(CacheResponse::SinglePageRetrieved { page }))
|
||||
Ok(Some(CacheResponse::SinglePageRetrieved { page_number, page }))
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -162,6 +168,9 @@ pub struct CachePageCommand {
|
||||
height: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CacheKillSignal;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RetrievePagesCommand {
|
||||
GetCurrentTwoPages { page_left_number: PageNumber },
|
||||
@ -170,10 +179,13 @@ pub enum RetrievePagesCommand {
|
||||
|
||||
pub enum CacheResponse {
|
||||
SinglePageRetrieved {
|
||||
page_number: PageNumber,
|
||||
page: Rc<MyPageType>,
|
||||
},
|
||||
TwoPagesRetrieved {
|
||||
page_number_left: PageNumber,
|
||||
page_left: Rc<MyPageType>,
|
||||
page_number_right : PageNumber,
|
||||
page_right: Rc<MyPageType>,
|
||||
},
|
||||
PageResolutionUpgraded {
|
||||
@ -186,6 +198,7 @@ pub struct SyncCacheCommandChannel {
|
||||
retrieve_commands: Vec<RetrievePagesCommand>,
|
||||
cache_commands: VecDeque<CachePageCommand>,
|
||||
priority_cache_commands: Vec<CachePageCommand>,
|
||||
kill_signals : Vec<CacheKillSignal>
|
||||
}
|
||||
|
||||
pub struct SyncCacheCommandSender {
|
||||
@ -193,6 +206,7 @@ pub struct SyncCacheCommandSender {
|
||||
}
|
||||
|
||||
pub struct SyncCacheCommandReceiver {
|
||||
cache_closed : bool,
|
||||
channel: Rc<RefCell<SyncCacheCommandChannel>>,
|
||||
}
|
||||
|
||||
@ -202,19 +216,20 @@ impl SyncCacheCommandChannel {
|
||||
retrieve_commands: Vec::new(),
|
||||
cache_commands: VecDeque::new(),
|
||||
priority_cache_commands: Vec::new(),
|
||||
kill_signals: Vec::new(),
|
||||
};
|
||||
let channel = Rc::new(RefCell::new(channel));
|
||||
|
||||
let sender = SyncCacheCommandSender {
|
||||
channel: Rc::clone(&channel),
|
||||
};
|
||||
let receiver = SyncCacheCommandReceiver { channel };
|
||||
let receiver = SyncCacheCommandReceiver { cache_closed: false, channel };
|
||||
(sender, receiver)
|
||||
}
|
||||
}
|
||||
|
||||
impl SyncCacheCommandSender {
|
||||
pub fn is_channel_open(&self) -> bool {
|
||||
pub fn _is_channel_open(&self) -> bool {
|
||||
Rc::strong_count(&self.channel) > 1
|
||||
}
|
||||
|
||||
@ -236,6 +251,7 @@ impl SyncCacheCommandSender {
|
||||
pub fn send_cache_commands(&self, pages: &[PageNumber], height: i32) {
|
||||
for &page in pages {
|
||||
// Make message in front the most important
|
||||
// TODO: the low res cach will never be actually done
|
||||
self.channel
|
||||
.borrow_mut()
|
||||
.cache_commands
|
||||
@ -246,6 +262,10 @@ impl SyncCacheCommandSender {
|
||||
.push_back(CachePageCommand { page, height });
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_kill_signal(&self) {
|
||||
self.channel.borrow_mut().kill_signals.push(CacheKillSignal);
|
||||
}
|
||||
}
|
||||
|
||||
impl SyncCacheCommandReceiver {
|
||||
@ -255,6 +275,10 @@ impl SyncCacheCommandReceiver {
|
||||
|
||||
pub fn receive_most_important_command(&self) -> Option<CacheCommand> {
|
||||
let mut channel = self.channel.borrow_mut();
|
||||
if let Some(command) = channel.kill_signals.pop() {
|
||||
// self.cache_closed = true;
|
||||
return None;
|
||||
}
|
||||
if let Some(command) = channel.priority_cache_commands.pop() {
|
||||
return Some(CacheCommand::Cache(command));
|
||||
} else if let Some(command) = channel.retrieve_commands.pop() {
|
||||
@ -266,17 +290,17 @@ impl SyncCacheCommandReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn_sync_cache<F>(document: Document, receiver: F) -> SyncCacheCommandSender
|
||||
pub fn spawn_sync_cache<F>(document: Document, color_mode:ColorMode,receiver: F) -> SyncCacheCommandSender
|
||||
where
|
||||
F: Fn(CacheResponse) + 'static,
|
||||
{
|
||||
let (command_sender, command_receiver) = SyncCacheCommandChannel::open();
|
||||
|
||||
let mut cache = PageCache::new(document, 30);
|
||||
let mut cache = PageCache::new(document, 30, color_mode);
|
||||
|
||||
// Besides the name, it is not in another thread
|
||||
glib::spawn_future_local(async move {
|
||||
while command_receiver.is_channel_open() {
|
||||
while command_receiver.is_channel_open() && !command_receiver.cache_closed {
|
||||
// Add delay to tell gtk to give rendering priority
|
||||
timeout_future(Duration::from_millis(1)).await;
|
||||
|
||||
|
146
src/color_mode.rs
Normal file
146
src/color_mode.rs
Normal file
@ -0,0 +1,146 @@
|
||||
use core::fmt;
|
||||
|
||||
use cairo::ImageSurface;
|
||||
use strum::EnumString;
|
||||
|
||||
#[derive(Clone, EnumString, Debug)]
|
||||
pub enum ColorMode {
|
||||
Normal,
|
||||
Dark,
|
||||
Sepia,
|
||||
}
|
||||
|
||||
impl fmt::Display for ColorMode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ColorMode {
|
||||
fn default() -> Self {
|
||||
ColorMode::Normal
|
||||
}
|
||||
}
|
||||
|
||||
impl ColorMode {
|
||||
fn transform_color(&self, r: u8, g: u8, b: u8) -> (u8, u8, u8) {
|
||||
// l of black is 0.13 (approx 0x22)
|
||||
match self {
|
||||
ColorMode::Normal => (r, g, b),
|
||||
ColorMode::Dark => {
|
||||
let (mut h, mut s, mut l) = rgb_to_hsl(r, g, b);
|
||||
l = (1.0 - l) * (1.0 - 0.13) + 0.13;
|
||||
hsl_to_rgb(h, s, l)
|
||||
}
|
||||
ColorMode::Sepia => {
|
||||
let (mut h, mut s, mut l) = rgb_to_hsl(r, g, b);
|
||||
h = h + 30.0;
|
||||
if h < 0.0 {
|
||||
h += 360.0;
|
||||
}
|
||||
s += 0.2;
|
||||
if s > 1.0 {
|
||||
s = 1.0;
|
||||
}
|
||||
|
||||
l = l * (1.0 - 0.13);
|
||||
hsl_to_rgb(h, s, l)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply color mode transformation to an RGB24 surface.
|
||||
pub fn apply_to_rgb24_surface(&self, surface: &mut ImageSurface) {
|
||||
let width = surface.width();
|
||||
let height = surface.height();
|
||||
let stride = surface.stride();
|
||||
|
||||
let mut data = surface.data().expect("Failed to get source surface data");
|
||||
|
||||
for y in 0..height {
|
||||
for x in 0..width {
|
||||
let offset = (y * stride + x * 4) as usize; // Rgb24: 3 bytes per pixel (R, G, B)
|
||||
|
||||
// Read source pixel
|
||||
let r = data[offset + 2];
|
||||
let g = data[offset + 1];
|
||||
let b = data[offset];
|
||||
|
||||
// Apply color transformation
|
||||
let (tr, tg, tb) = self.transform_color(r, g, b);
|
||||
|
||||
// Write transformed pixel to destination surface
|
||||
data[offset + 2] = tr;
|
||||
data[offset + 1] = tg;
|
||||
data[offset] = tb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// h from 0 to 360
|
||||
// s from 0 to 1
|
||||
// l from 0 to 1
|
||||
fn rgb_to_hsl(r: u8, g: u8, b: u8) -> (f64, f64, f64) {
|
||||
let r = r as f64 / 255.0;
|
||||
let g = g as f64 / 255.0;
|
||||
let b = b as f64 / 255.0;
|
||||
|
||||
let max = r.max(g).max(b);
|
||||
let min = r.min(g).min(b);
|
||||
let delta = max - min;
|
||||
|
||||
// Calculate Lightness
|
||||
let l = (max + min) / 2.0;
|
||||
|
||||
// Calculate Saturation
|
||||
let s = if delta == 0.0 {
|
||||
0.0
|
||||
} else if l < 0.5 {
|
||||
delta / (max + min)
|
||||
} else {
|
||||
delta / (2.0 - max - min)
|
||||
};
|
||||
|
||||
// Calculate Hue
|
||||
let h = if delta == 0.0 {
|
||||
0.0
|
||||
} else if max == r {
|
||||
60.0 * (((g - b) / delta) % 6.0)
|
||||
} else if max == g {
|
||||
60.0 * (((b - r) / delta) + 2.0)
|
||||
} else {
|
||||
60.0 * (((r - g) / delta) + 4.0)
|
||||
};
|
||||
|
||||
let h = if h < 0.0 { h + 360.0 } else { h };
|
||||
|
||||
(h, s, l)
|
||||
}
|
||||
|
||||
fn hsl_to_rgb(h: f64, s: f64, l: f64) -> (u8, u8, u8) {
|
||||
let c = (1.0 - (2.0 * l - 1.0).abs()) * s; // Chroma
|
||||
let x = c * (1.0 - ((h / 60.0) % 2.0 - 1.0).abs());
|
||||
let m = l - c / 2.0;
|
||||
|
||||
let (r, g, b) = if (0.0..60.0).contains(&h) {
|
||||
(c, x, 0.0)
|
||||
} else if (60.0..120.0).contains(&h) {
|
||||
(x, c, 0.0)
|
||||
} else if (120.0..180.0).contains(&h) {
|
||||
(0.0, c, x)
|
||||
} else if (180.0..240.0).contains(&h) {
|
||||
(0.0, x, c)
|
||||
} else if (240.0..300.0).contains(&h) {
|
||||
(x, 0.0, c)
|
||||
} else {
|
||||
(c, 0.0, x)
|
||||
};
|
||||
|
||||
// Convert back to [0, 255]
|
||||
(
|
||||
((r + m) * 255.0).round() as u8,
|
||||
((g + m) * 255.0).round() as u8,
|
||||
((b + m) * 255.0).round() as u8,
|
||||
)
|
||||
}
|
20
src/draw.rs
20
src/draw.rs
@ -1,12 +1,18 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use cairo::{Context, ImageSurface};
|
||||
use cairo::{Context, ImageSurface, ImageSurfaceData};
|
||||
use glib::Bytes;
|
||||
use gtk::gdk::Texture;
|
||||
use log::debug;
|
||||
use poppler::Page;
|
||||
|
||||
pub fn draw_pages_to_texture(pages: &[Rc<Page>], area_height: i32) -> Texture {
|
||||
use crate::color_mode::ColorMode;
|
||||
|
||||
pub fn draw_pages_to_texture(
|
||||
pages: &[Rc<Page>],
|
||||
area_height: i32,
|
||||
color_mode: &ColorMode,
|
||||
) -> Texture {
|
||||
let area_height = i32::max(100, area_height);
|
||||
let total_width_normalized: f64 = pages
|
||||
.iter()
|
||||
@ -15,9 +21,13 @@ pub fn draw_pages_to_texture(pages: &[Rc<Page>], area_height: i32) -> Texture {
|
||||
.sum();
|
||||
let area_width = (total_width_normalized * area_height as f64 + 0.5) as i32;
|
||||
|
||||
let surface = ImageSurface::create(cairo::Format::Rgb24, area_width, area_height).unwrap();
|
||||
let context = Context::new(&surface).unwrap();
|
||||
draw_pages(pages, &context, area_width, area_height);
|
||||
let mut surface = ImageSurface::create(cairo::Format::Rgb24, area_width, area_height).unwrap();
|
||||
{
|
||||
let context = Context::new(&surface).unwrap();
|
||||
draw_pages(pages, &context, area_width, area_height);
|
||||
} // Assure the context gets dropped and the data of the surface can be accessed again
|
||||
|
||||
color_mode.apply_to_rgb24_surface(&mut surface);
|
||||
|
||||
let mut stream: Vec<u8> = Vec::new();
|
||||
surface.write_to_png(&mut stream).unwrap();
|
||||
|
13
src/main.rs
13
src/main.rs
@ -1,12 +1,13 @@
|
||||
mod cache;
|
||||
mod color_mode;
|
||||
mod draw;
|
||||
mod ui;
|
||||
|
||||
use clap::Parser;
|
||||
use env_logger::Env;
|
||||
use gio::Settings;
|
||||
use gtk::prelude::*;
|
||||
use gtk::Application;
|
||||
use log::debug;
|
||||
use std::cell::RefCell;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
@ -23,19 +24,19 @@ struct Cli {
|
||||
fn main() {
|
||||
env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init();
|
||||
let cli = Cli::parse();
|
||||
debug!("Parse args");
|
||||
let app = Application::builder().application_id(APP_ID).build();
|
||||
|
||||
app.connect_activate(move |app| {
|
||||
let ui = build_ui(app);
|
||||
let settings = Settings::new(APP_ID);
|
||||
let ui = build_ui(app, settings);
|
||||
if let Some(file) = cli.file.as_ref() {
|
||||
ui::load_document(file, Rc::clone(&ui));
|
||||
ui::load_document(file, Rc::clone(&ui), 0);
|
||||
}
|
||||
});
|
||||
|
||||
app.run_with_args(&[] as &[&str]);
|
||||
}
|
||||
|
||||
fn build_ui(app: &Application) -> Rc<RefCell<Ui>> {
|
||||
Ui::build(app)
|
||||
fn build_ui(app: &Application, settings: Settings) -> Rc<RefCell<Ui>> {
|
||||
Ui::build(app, settings)
|
||||
}
|
||||
|
258
src/ui.rs
258
src/ui.rs
@ -2,24 +2,31 @@ use std::{
|
||||
cell::RefCell,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
str::FromStr,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use gio::Settings;
|
||||
use gtk::{
|
||||
glib, Application, ApplicationWindow, Box, Button, FileChooserAction, FileChooserDialog,
|
||||
HeaderBar, Label, Overlay, Picture, ResponseType,
|
||||
HeaderBar, Label, Overlay, Picture, ResponseType, ToggleButton,
|
||||
};
|
||||
use log::debug;
|
||||
|
||||
use crate::cache::{self, PageNumber, SyncCacheCommandSender};
|
||||
use crate::{
|
||||
cache::{self, CacheResponse, PageNumber, SyncCacheCommandSender},
|
||||
color_mode::{self, ColorMode},
|
||||
};
|
||||
use glib::clone;
|
||||
use gtk::prelude::*;
|
||||
|
||||
pub struct Ui {
|
||||
settings: Settings,
|
||||
window: ApplicationWindow,
|
||||
bottom_bar: gtk::Box,
|
||||
header_bar: gtk::HeaderBar,
|
||||
page_indicator: gtk::Label,
|
||||
pub color_mode: ColorMode,
|
||||
pub app_wrapper: Overlay,
|
||||
pub image_container: Box,
|
||||
pub image_left: Picture,
|
||||
@ -29,14 +36,16 @@ pub struct Ui {
|
||||
}
|
||||
|
||||
pub struct DocumentCanvas {
|
||||
pub document_path: PathBuf,
|
||||
pub current_page_number: usize,
|
||||
pub num_pages: Option<usize>,
|
||||
page_cache_sender: SyncCacheCommandSender,
|
||||
}
|
||||
|
||||
impl DocumentCanvas {
|
||||
pub fn new(page_cache_sender: SyncCacheCommandSender) -> Self {
|
||||
pub fn new(document_path: PathBuf, page_cache_sender: SyncCacheCommandSender) -> Self {
|
||||
DocumentCanvas {
|
||||
document_path,
|
||||
current_page_number: 0,
|
||||
num_pages: None,
|
||||
page_cache_sender,
|
||||
@ -56,20 +65,28 @@ impl DocumentCanvas {
|
||||
}
|
||||
|
||||
pub fn cache_initial_pages(&self, area_height: i32) {
|
||||
self.priority_cache_current_pages(area_height);
|
||||
}
|
||||
|
||||
pub fn priority_cache_current_pages(&self, area_height: i32) {
|
||||
self.page_cache_sender.send_priority_cache_commands(
|
||||
&[self.current_page_number, self.current_page_number + 1],
|
||||
area_height,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn purge_cache(&self) {
|
||||
self.page_cache_sender.send_kill_signal();
|
||||
}
|
||||
|
||||
pub fn cache_surrounding_pages(&self, area_height: i32) {
|
||||
self.page_cache_sender.send_cache_commands(
|
||||
&[
|
||||
self.current_page_number.saturating_sub(2),
|
||||
self.current_page_number.saturating_sub(1),
|
||||
self.current_page_number,
|
||||
self.current_page_number + 1,
|
||||
self.current_page_number.saturating_sub(1),
|
||||
self.current_page_number + 2,
|
||||
self.current_page_number.saturating_sub(2),
|
||||
self.current_page_number + 3,
|
||||
],
|
||||
area_height,
|
||||
@ -100,16 +117,24 @@ impl DocumentCanvas {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_fullscreen(ui: &Ui) {
|
||||
match !ui.window.is_fullscreen() {
|
||||
pub fn set_fullscreen(ui: &Ui, fullscreen: bool) {
|
||||
match fullscreen {
|
||||
true => {
|
||||
ui.header_bar.hide();
|
||||
ui.bottom_bar.hide();
|
||||
ui.window.fullscreen();
|
||||
ui.document_canvas
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.cache_surrounding_pages(ui.image_container.height() + ui.header_bar.height());
|
||||
|
||||
let new_area_height = ui.image_container.height() + ui.header_bar.height();
|
||||
if ui.document_canvas.is_some() {
|
||||
ui.document_canvas
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.priority_cache_current_pages(new_area_height);
|
||||
ui.document_canvas
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.cache_surrounding_pages(new_area_height);
|
||||
}
|
||||
}
|
||||
false => {
|
||||
ui.header_bar.show();
|
||||
@ -117,6 +142,11 @@ pub fn toggle_fullscreen(ui: &Ui) {
|
||||
ui.window.unfullscreen();
|
||||
}
|
||||
}
|
||||
ui.settings.set_boolean("fullscreen", fullscreen).unwrap();
|
||||
}
|
||||
|
||||
pub fn toggle_fullscreen(ui: &Ui) {
|
||||
set_fullscreen(ui, !ui.window.is_fullscreen());
|
||||
}
|
||||
|
||||
fn update_page_status(ui: &Ui) {
|
||||
@ -193,9 +223,36 @@ fn process_left_click(ui: &mut Ui, x: f64, y: f64) {
|
||||
}
|
||||
|
||||
impl Ui {
|
||||
pub fn build(app: &Application) -> Rc<RefCell<Ui>> {
|
||||
pub fn build(app: &Application, settings: Settings) -> Rc<RefCell<Ui>> {
|
||||
debug!("building ui");
|
||||
let open_file_button = Button::from_icon_name("document-open");
|
||||
let fullscreen_button = Button::from_icon_name("view-fullscreen");
|
||||
let normal_color_mode_button = ToggleButton::builder().label("Std").build();
|
||||
let dark_color_mode_button = ToggleButton::builder()
|
||||
.label("Dark")
|
||||
.group(&normal_color_mode_button)
|
||||
.build();
|
||||
let sepia_color_mode_button = ToggleButton::builder()
|
||||
.label("Sepia")
|
||||
.group(&normal_color_mode_button)
|
||||
.build();
|
||||
|
||||
let button_container = Box::builder()
|
||||
.spacing(10)
|
||||
.hexpand(true)
|
||||
.orientation(gtk::Orientation::Horizontal)
|
||||
.build();
|
||||
let color_mode_button_container = Box::builder()
|
||||
.spacing(0)
|
||||
.hexpand(true)
|
||||
.orientation(gtk::Orientation::Horizontal)
|
||||
.build();
|
||||
color_mode_button_container.append(&normal_color_mode_button);
|
||||
color_mode_button_container.append(&dark_color_mode_button);
|
||||
color_mode_button_container.append(&sepia_color_mode_button);
|
||||
button_container.append(&open_file_button);
|
||||
button_container.append(&fullscreen_button);
|
||||
button_container.append(&color_mode_button_container);
|
||||
|
||||
let image_container = Box::builder()
|
||||
.spacing(0)
|
||||
@ -234,8 +291,17 @@ impl Ui {
|
||||
.width_request(600)
|
||||
.height_request(400)
|
||||
.build();
|
||||
window.present();
|
||||
|
||||
let color_mode = ColorMode::from_str(&settings.string("color-mode")).unwrap_or_default();
|
||||
match color_mode {
|
||||
ColorMode::Normal => normal_color_mode_button.set_active(true),
|
||||
ColorMode::Dark => dark_color_mode_button.set_active(true),
|
||||
ColorMode::Sepia => sepia_color_mode_button.set_active(true),
|
||||
};
|
||||
|
||||
let ui = Ui {
|
||||
settings,
|
||||
window,
|
||||
app_wrapper,
|
||||
bottom_bar: Box::builder()
|
||||
@ -249,10 +315,11 @@ impl Ui {
|
||||
image_right,
|
||||
document_canvas: None,
|
||||
last_touch_time: None,
|
||||
color_mode,
|
||||
};
|
||||
let ui = Rc::new(RefCell::new(ui));
|
||||
|
||||
ui.borrow().header_bar.pack_start(&open_file_button);
|
||||
ui.borrow().header_bar.pack_start(&button_container);
|
||||
ui.borrow().app_wrapper.add_overlay(&ui.borrow().bottom_bar);
|
||||
ui.borrow().bottom_bar.append(&ui.borrow().page_indicator);
|
||||
|
||||
@ -280,12 +347,68 @@ impl Ui {
|
||||
choose_file(Rc::clone(&ui), &ui.borrow().window);
|
||||
}),
|
||||
);
|
||||
fullscreen_button.connect_clicked(
|
||||
glib::clone!(@strong ui => @default-panic, move |_button| {
|
||||
toggle_fullscreen(&ui.borrow());
|
||||
}),
|
||||
);
|
||||
normal_color_mode_button.connect_clicked(
|
||||
glib::clone!(@strong ui => @default-panic, move |_button| {
|
||||
switch_color_mode(Rc::clone(&ui), ColorMode::Normal);
|
||||
}),
|
||||
);
|
||||
dark_color_mode_button.connect_clicked(
|
||||
glib::clone!(@strong ui => @default-panic, move |_button| {
|
||||
switch_color_mode(Rc::clone(&ui), ColorMode::Dark);
|
||||
}),
|
||||
);
|
||||
sepia_color_mode_button.connect_clicked(
|
||||
glib::clone!(@strong ui => @default-panic, move |_button| {
|
||||
switch_color_mode(Rc::clone(&ui), ColorMode::Sepia);
|
||||
}),
|
||||
);
|
||||
|
||||
ui.borrow().window.present();
|
||||
|
||||
if ui.borrow().settings.boolean("fullscreen") {
|
||||
set_fullscreen(&ui.borrow(), true);
|
||||
}
|
||||
|
||||
ui
|
||||
}
|
||||
}
|
||||
|
||||
fn switch_color_mode(ui: Rc<RefCell<Ui>>, color_mode: ColorMode) {
|
||||
ui.borrow()
|
||||
.settings
|
||||
.set_string("color-mode", &color_mode.to_string())
|
||||
.unwrap();
|
||||
|
||||
ui.borrow_mut().color_mode = color_mode;
|
||||
|
||||
if ui.borrow().document_canvas.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
ui.borrow().document_canvas.as_ref().unwrap().purge_cache();
|
||||
|
||||
let path = ui
|
||||
.borrow()
|
||||
.document_canvas
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.document_path
|
||||
.clone();
|
||||
let current_page_number = ui
|
||||
.borrow()
|
||||
.document_canvas
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.current_page_number;
|
||||
|
||||
load_document(path, Rc::clone(&ui), current_page_number);
|
||||
}
|
||||
|
||||
fn choose_file(ui: Rc<RefCell<Ui>>, window: &ApplicationWindow) {
|
||||
let filechooser = FileChooserDialog::builder()
|
||||
.title("Choose a PDF...")
|
||||
@ -298,59 +421,36 @@ fn choose_file(ui: Rc<RefCell<Ui>>, window: &ApplicationWindow) {
|
||||
filechooser.connect_response(move |d, response| {
|
||||
if response == ResponseType::Accept {
|
||||
let path = d.file().unwrap().path().unwrap();
|
||||
load_document(path, Rc::clone(&ui));
|
||||
|
||||
if ui.borrow().document_canvas.is_some() {
|
||||
ui.borrow().document_canvas.as_ref().unwrap().purge_cache();
|
||||
}
|
||||
|
||||
load_document(path, Rc::clone(&ui), 0);
|
||||
}
|
||||
d.destroy();
|
||||
});
|
||||
filechooser.show()
|
||||
}
|
||||
|
||||
pub fn load_document(file: impl AsRef<Path>, ui: Rc<RefCell<Ui>>) {
|
||||
pub fn load_document(file: impl AsRef<Path>, ui: Rc<RefCell<Ui>>, initial_page_number: usize) {
|
||||
debug!("Loading file...");
|
||||
// TODO: catch errors, maybe show error dialog
|
||||
let path: PathBuf = file.as_ref().to_path_buf();
|
||||
let uri = format!("file://{}", path.to_str().unwrap());
|
||||
let document = poppler::Document::from_file(&uri, None).unwrap();
|
||||
let num_pages = document.n_pages() as usize;
|
||||
let color_mode = ui.borrow().color_mode.clone();
|
||||
|
||||
let sender = cache::spawn_sync_cache(
|
||||
document,
|
||||
clone!(@weak ui => move |cache_response| match cache_response {
|
||||
cache::CacheResponse::SinglePageRetrieved { page } => {
|
||||
ui.borrow_mut().image_left.set_paintable(Some(page.as_ref()));
|
||||
if ui.borrow().document_canvas.as_ref().map(|canvas| canvas.num_pages.unwrap_or(0)).unwrap_or(0) > 1 {
|
||||
// Make image invisible but keep free space in layout
|
||||
ui.borrow_mut().image_right.set_opacity(0.0);
|
||||
} else {
|
||||
// Make image invisible and center left page in layout
|
||||
ui.borrow_mut().image_right.set_visible(false);
|
||||
}
|
||||
let area_height = ui.borrow().image_container.height();
|
||||
ui.borrow().document_canvas.as_ref().unwrap().cache_surrounding_pages(area_height);
|
||||
}
|
||||
cache::CacheResponse::TwoPagesRetrieved {
|
||||
page_left,
|
||||
page_right,
|
||||
} => {
|
||||
ui.borrow_mut().image_left.set_paintable(Some(page_left.as_ref()));
|
||||
ui.borrow_mut().image_right.set_paintable(Some(page_right.as_ref()));
|
||||
ui.borrow_mut().image_right.set_visible(true);
|
||||
ui.borrow_mut().image_right.set_opacity(1.0);
|
||||
let area_height = ui.borrow().image_container.height();
|
||||
ui.borrow().document_canvas.as_ref().unwrap().cache_surrounding_pages(area_height);
|
||||
},
|
||||
cache::CacheResponse::PageResolutionUpgraded { page_number, page } => {
|
||||
if ui.borrow().document_canvas.as_ref().unwrap().is_left_page(page_number){
|
||||
ui.borrow_mut().image_left.set_paintable(Some(page.as_ref()));
|
||||
} else if ui.borrow().document_canvas.as_ref().unwrap().is_right_page(page_number){
|
||||
ui.borrow_mut().image_right.set_paintable(Some(page.as_ref()));
|
||||
}
|
||||
}
|
||||
}),
|
||||
color_mode,
|
||||
clone!(@weak ui => move |cache_response| handle_cache_response(ui, cache_response)),
|
||||
);
|
||||
|
||||
let mut document_canvas = DocumentCanvas::new(sender);
|
||||
let mut document_canvas = DocumentCanvas::new(path, sender);
|
||||
document_canvas.num_pages = Some(num_pages);
|
||||
document_canvas.current_page_number = initial_page_number;
|
||||
document_canvas.cache_initial_pages(ui.borrow().image_container.height());
|
||||
|
||||
ui.borrow_mut().document_canvas = Some(document_canvas);
|
||||
@ -358,3 +458,65 @@ pub fn load_document(file: impl AsRef<Path>, ui: Rc<RefCell<Ui>>) {
|
||||
update_page_status(&ui.borrow());
|
||||
debug!("finished loading document");
|
||||
}
|
||||
|
||||
fn handle_cache_response(ui: Rc<RefCell<Ui>>, cache_response: CacheResponse) {
|
||||
if let Some(canvas) = ui.borrow().document_canvas.as_ref() {
|
||||
let image_left = &ui.borrow().image_left;
|
||||
let image_right = &ui.borrow().image_right;
|
||||
let area_height = ui.borrow().image_container.height();
|
||||
|
||||
match cache_response {
|
||||
cache::CacheResponse::SinglePageRetrieved { page_number, page } => {
|
||||
if !canvas.is_left_page(page_number) {
|
||||
debug!("Retrieved page with non up-to-date page_number from cache, ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
image_left.set_paintable(Some(page.as_ref()));
|
||||
image_left.queue_draw();
|
||||
if canvas.num_pages.unwrap_or(0) > 1 {
|
||||
// Make image invisible but keep free space in layout
|
||||
image_right.set_opacity(0.0);
|
||||
} else {
|
||||
// Make image invisible and center left page in layout
|
||||
image_right.set_visible(false);
|
||||
}
|
||||
canvas.cache_surrounding_pages(area_height);
|
||||
}
|
||||
cache::CacheResponse::TwoPagesRetrieved {
|
||||
page_number_left,
|
||||
page_left,
|
||||
page_number_right,
|
||||
page_right,
|
||||
} => {
|
||||
if !canvas.is_left_page(page_number_left)
|
||||
|| !canvas.is_right_page(page_number_right)
|
||||
{
|
||||
debug!("Retrieved pages with non up-to-date page_number from cache, ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
image_left.set_paintable(Some(page_left.as_ref()));
|
||||
image_right.set_paintable(Some(page_right.as_ref()));
|
||||
image_right.set_visible(true);
|
||||
image_right.set_opacity(1.0);
|
||||
|
||||
image_left.queue_draw();
|
||||
image_right.queue_draw();
|
||||
|
||||
canvas.cache_surrounding_pages(area_height);
|
||||
}
|
||||
cache::CacheResponse::PageResolutionUpgraded { page_number, page } => {
|
||||
if canvas.is_left_page(page_number) {
|
||||
image_left.set_paintable(Some(page.as_ref()));
|
||||
|
||||
image_left.queue_draw();
|
||||
} else if canvas.is_right_page(page_number) {
|
||||
image_right.set_paintable(Some(page.as_ref()));
|
||||
|
||||
image_right.queue_draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user