feat(bg): multi-background support with kraft, manuscript, composition, and custom image
This commit is contained in:
476
Cargo.lock
generated
476
Cargo.lock
generated
@@ -138,6 +138,24 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aligned"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685"
|
||||
dependencies = [
|
||||
"as-slice",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aligned-vec"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b"
|
||||
dependencies = [
|
||||
"equator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-activity"
|
||||
version = "0.6.1"
|
||||
@@ -178,6 +196,12 @@ version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
|
||||
|
||||
[[package]]
|
||||
name = "arboard"
|
||||
version = "3.6.1"
|
||||
@@ -198,6 +222,17 @@ dependencies = [
|
||||
"x11rb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arg_enum_proc_macro"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.9"
|
||||
@@ -216,6 +251,15 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
|
||||
|
||||
[[package]]
|
||||
name = "as-slice"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516"
|
||||
dependencies = [
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ash"
|
||||
version = "0.38.0+1.3.281"
|
||||
@@ -463,6 +507,49 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "av-scenechange"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394"
|
||||
dependencies = [
|
||||
"aligned",
|
||||
"anyhow",
|
||||
"arg_enum_proc_macro",
|
||||
"arrayvec",
|
||||
"log",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"pastey",
|
||||
"rayon",
|
||||
"thiserror 2.0.18",
|
||||
"v_frame",
|
||||
"y4m",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "av1-grain"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arrayvec",
|
||||
"log",
|
||||
"nom",
|
||||
"num-rational",
|
||||
"v_frame",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "avif-serialize"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7178fe5f7d460b13895ebb9dcb28a3a6216d2df2574a0806cb51b555d297f38"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.8.0"
|
||||
@@ -478,6 +565,12 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
@@ -493,6 +586,15 @@ dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitstream-io"
|
||||
version = "4.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eff00be299a18769011411c9def0d827e8f2d7bf0c3dbf53633147a8867fd1f"
|
||||
dependencies = [
|
||||
"no_std_io2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block"
|
||||
version = "0.1.6"
|
||||
@@ -539,6 +641,12 @@ dependencies = [
|
||||
"piper",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "built"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.20.2"
|
||||
@@ -686,6 +794,12 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.7"
|
||||
@@ -773,6 +887,25 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
@@ -990,6 +1123,12 @@ dependencies = [
|
||||
"winit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "emath"
|
||||
version = "0.31.1"
|
||||
@@ -1069,11 +1208,32 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"eframe",
|
||||
"epub",
|
||||
"image",
|
||||
"rfd",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equator"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc"
|
||||
dependencies = [
|
||||
"equator-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equator-macro"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
@@ -1117,6 +1277,21 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exr"
|
||||
version = "1.74.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"half",
|
||||
"lebe",
|
||||
"miniz_oxide",
|
||||
"rayon-core",
|
||||
"smallvec",
|
||||
"zune-inflate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.4.1"
|
||||
@@ -1325,6 +1500,16 @@ dependencies = [
|
||||
"wasip3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gl_generator"
|
||||
version = "0.14.0"
|
||||
@@ -1620,12 +1805,38 @@ checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder-lite",
|
||||
"color_quant",
|
||||
"exr",
|
||||
"gif",
|
||||
"image-webp",
|
||||
"moxcms",
|
||||
"num-traits",
|
||||
"png",
|
||||
"qoi",
|
||||
"ravif",
|
||||
"rayon",
|
||||
"rgb",
|
||||
"tiff",
|
||||
"zune-core",
|
||||
"zune-jpeg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image-webp"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3"
|
||||
dependencies = [
|
||||
"byteorder-lite",
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imgref"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40fac9d56ed6437b198fddba683305e8e2d651aa42647f00f5ae542e7f5c94a2"
|
||||
|
||||
[[package]]
|
||||
name = "immutable-chunkmap"
|
||||
version = "2.1.2"
|
||||
@@ -1647,6 +1858,26 @@ dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "interpolate_name"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
@@ -1756,12 +1987,28 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||
|
||||
[[package]]
|
||||
name = "lebe"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.186"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
||||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.9"
|
||||
@@ -1823,6 +2070,15 @@ version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "loop9"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
|
||||
dependencies = [
|
||||
"imgref",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
version = "0.0.6"
|
||||
@@ -1832,6 +2088,16 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maybe-rayon"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
@@ -1952,6 +2218,12 @@ dependencies = [
|
||||
"jni-sys 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.29.0"
|
||||
@@ -1965,12 +2237,77 @@ dependencies = [
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "no_std_io2"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nohash-hasher"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "8.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "noop_proc_macro"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
@@ -2362,6 +2699,12 @@ version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pastey"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.2"
|
||||
@@ -2501,6 +2844,19 @@ name = "profiling"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5"
|
||||
dependencies = [
|
||||
"profiling-procmacros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "profiling-procmacros"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pxfm"
|
||||
@@ -2508,6 +2864,15 @@ version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f"
|
||||
|
||||
[[package]]
|
||||
name = "qoi"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "2.0.1"
|
||||
@@ -2613,12 +2978,82 @@ dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rav1e"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b"
|
||||
dependencies = [
|
||||
"aligned-vec",
|
||||
"arbitrary",
|
||||
"arg_enum_proc_macro",
|
||||
"arrayvec",
|
||||
"av-scenechange",
|
||||
"av1-grain",
|
||||
"bitstream-io",
|
||||
"built",
|
||||
"cfg-if",
|
||||
"interpolate_name",
|
||||
"itertools",
|
||||
"libc",
|
||||
"libfuzzer-sys",
|
||||
"log",
|
||||
"maybe-rayon",
|
||||
"new_debug_unreachable",
|
||||
"noop_proc_macro",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"paste",
|
||||
"profiling",
|
||||
"rand 0.9.4",
|
||||
"rand_chacha 0.9.0",
|
||||
"simd_helpers",
|
||||
"thiserror 2.0.18",
|
||||
"v_frame",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ravif"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e52310197d971b0f5be7fe6b57530dcd27beb35c1b013f29d66c1ad73fbbcc45"
|
||||
dependencies = [
|
||||
"avif-serialize",
|
||||
"imgref",
|
||||
"loop9",
|
||||
"quick-error",
|
||||
"rav1e",
|
||||
"rayon",
|
||||
"rgb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "raw-window-handle"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
@@ -2705,6 +3140,12 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
@@ -2895,6 +3336,15 @@ dependencies = [
|
||||
"simdutf8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd_helpers"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
|
||||
dependencies = [
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simdutf8"
|
||||
version = "0.1.5"
|
||||
@@ -3330,6 +3780,17 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "v_frame"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2"
|
||||
dependencies = [
|
||||
"aligned-vec",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
@@ -4239,6 +4700,12 @@ version = "0.8.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f"
|
||||
|
||||
[[package]]
|
||||
name = "y4m"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448"
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.2"
|
||||
@@ -4520,6 +4987,15 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9"
|
||||
|
||||
[[package]]
|
||||
name = "zune-inflate"
|
||||
version = "0.2.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-jpeg"
|
||||
version = "0.5.15"
|
||||
|
||||
@@ -14,6 +14,7 @@ epub = "1.2"
|
||||
rfd = "0.15"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
image = "0.25"
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
|
||||
111
src/app.rs
111
src/app.rs
@@ -1,7 +1,7 @@
|
||||
use crate::book::Book;
|
||||
use crate::persistence;
|
||||
use crate::style::StyleProfile;
|
||||
use crate::theme::{self, Settings};
|
||||
use crate::theme::{self, BgType, Settings};
|
||||
use eframe::egui;
|
||||
use std::path::PathBuf;
|
||||
|
||||
@@ -10,6 +10,9 @@ pub struct App {
|
||||
settings: Settings,
|
||||
settings_dir: std::path::PathBuf,
|
||||
kraft_texture: Option<egui::TextureHandle>,
|
||||
manuscript_texture: Option<egui::TextureHandle>,
|
||||
composition_texture: Option<egui::TextureHandle>,
|
||||
custom_texture: Option<egui::TextureHandle>,
|
||||
}
|
||||
|
||||
pub struct AppState {
|
||||
@@ -53,7 +56,6 @@ impl App {
|
||||
let settings_dir = persistence::settings_dir();
|
||||
let settings = persistence::load_settings(&settings_dir).unwrap_or_default();
|
||||
cc.egui_ctx.set_style(theme::create_style(&settings.theme));
|
||||
let kraft_texture = Some(crate::texture::generate_kraft_paper(&cc.egui_ctx));
|
||||
Self {
|
||||
state: AppState {
|
||||
book: None,
|
||||
@@ -65,7 +67,10 @@ impl App {
|
||||
},
|
||||
settings,
|
||||
settings_dir,
|
||||
kraft_texture,
|
||||
kraft_texture: Some(crate::texture::generate_kraft_paper(&cc.egui_ctx)),
|
||||
manuscript_texture: Some(crate::texture::generate_manuscript(&cc.egui_ctx)),
|
||||
composition_texture: Some(crate::texture::generate_composition(&cc.egui_ctx)),
|
||||
custom_texture: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,25 +183,83 @@ impl App {
|
||||
|
||||
impl eframe::App for App {
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
let use_kraft = self.settings.use_kraft_bg;
|
||||
let bg_type = self.settings.bg_type.clone();
|
||||
let has_bg = bg_type.has_background();
|
||||
|
||||
// 牛皮纸模式:全窗口绘制纹理 + 面板透明
|
||||
if use_kraft {
|
||||
if let Some(texture) = &self.kraft_texture {
|
||||
// 有背景时面板设为透明
|
||||
if has_bg {
|
||||
ctx.style_mut(|s| {
|
||||
s.visuals.panel_fill = egui::Color32::TRANSPARENT;
|
||||
s.visuals.window_fill = egui::Color32::TRANSPARENT;
|
||||
s.visuals.faint_bg_color = egui::Color32::TRANSPARENT;
|
||||
});
|
||||
let viewport_rect =
|
||||
ctx.input(|i| i.screen_rect());
|
||||
}
|
||||
|
||||
// 全窗口背景纹理
|
||||
let viewport_rect = ctx.input(|i| i.screen_rect());
|
||||
match bg_type {
|
||||
BgType::Kraft => {
|
||||
if let Some(tex) = &self.kraft_texture {
|
||||
crate::texture::draw_tiled_bg(
|
||||
&ctx.layer_painter(egui::LayerId::background()),
|
||||
viewport_rect,
|
||||
texture,
|
||||
tex,
|
||||
);
|
||||
}
|
||||
}
|
||||
BgType::Manuscript => {
|
||||
if let Some(tex) = &self.manuscript_texture {
|
||||
crate::texture::draw_tiled_bg(
|
||||
&ctx.layer_painter(egui::LayerId::background()),
|
||||
viewport_rect,
|
||||
tex,
|
||||
);
|
||||
}
|
||||
}
|
||||
BgType::Composition => {
|
||||
if let Some(tex) = &self.composition_texture {
|
||||
crate::texture::draw_tiled_bg(
|
||||
&ctx.layer_painter(egui::LayerId::background()),
|
||||
viewport_rect,
|
||||
tex,
|
||||
);
|
||||
}
|
||||
}
|
||||
BgType::Custom(ref path) if !path.is_empty() => {
|
||||
if self.custom_texture.is_none() {
|
||||
match image::ImageReader::open(path) {
|
||||
Ok(reader) => match reader.decode() {
|
||||
Ok(img) => {
|
||||
let size = [img.width() as usize, img.height() as usize];
|
||||
let pixels: Vec<egui::Color32> = img
|
||||
.to_rgba8()
|
||||
.pixels()
|
||||
.map(|p| {
|
||||
egui::Color32::from_rgba_unmultiplied(p[0], p[1], p[2], p[3])
|
||||
})
|
||||
.collect();
|
||||
let image = egui::ColorImage { size, pixels };
|
||||
self.custom_texture = Some(
|
||||
ctx.load_texture("custom_bg", image, Default::default()),
|
||||
);
|
||||
}
|
||||
Err(_) => {}
|
||||
},
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
if let Some(tex) = &self.custom_texture {
|
||||
let painter = &ctx.layer_painter(egui::LayerId::background());
|
||||
painter.image(
|
||||
tex.id(),
|
||||
viewport_rect,
|
||||
egui::Rect::from_min_max(egui::pos2(0.0, 0.0), egui::pos2(1.0, 1.0)),
|
||||
egui::Color32::WHITE,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.state.book.is_none() {
|
||||
self.welcome_view(ctx);
|
||||
@@ -214,7 +277,7 @@ impl eframe::App for App {
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
let book = self.state.book.as_mut().unwrap();
|
||||
let action = crate::reader::reading_view(
|
||||
let action = crate::reader::reading_view(
|
||||
ui,
|
||||
book,
|
||||
&mut self.state.current_section,
|
||||
@@ -222,7 +285,7 @@ let action = crate::reader::reading_view(
|
||||
&mut self.state.sidebar_open,
|
||||
&mut style,
|
||||
&theme_copy,
|
||||
use_kraft,
|
||||
bg_type.clone(),
|
||||
&file_path,
|
||||
&profile_names,
|
||||
);
|
||||
@@ -234,7 +297,7 @@ let action = crate::reader::reading_view(
|
||||
self.state.current_page = 0;
|
||||
}
|
||||
|
||||
// Switch profile immediately: copy all settings from the selected profile
|
||||
// Switch profile immediately
|
||||
if let Some(ref target) = action.switch_to_profile {
|
||||
if let Some(profile) = self.settings.profiles.iter()
|
||||
.find(|p| p.name == *target)
|
||||
@@ -249,8 +312,24 @@ let action = crate::reader::reading_view(
|
||||
}
|
||||
}
|
||||
|
||||
if action.toggle_kraft_bg {
|
||||
self.settings.use_kraft_bg = !self.settings.use_kraft_bg;
|
||||
if let Some(new_bg) = action.switch_bg {
|
||||
self.settings.bg_type = new_bg;
|
||||
// 切换背景时,如果选自定义图片则弹出文件选择器
|
||||
if let BgType::Custom(_) = &self.settings.bg_type {
|
||||
if let Some(p) = rfd::FileDialog::new()
|
||||
.add_filter("Images", &["png", "jpg", "jpeg", "bmp", "webp"])
|
||||
.pick_file()
|
||||
{
|
||||
self.settings.bg_type = BgType::Custom(p.to_string_lossy().to_string());
|
||||
self.custom_texture = None;
|
||||
} else {
|
||||
self.settings.bg_type = BgType::None;
|
||||
}
|
||||
}
|
||||
// 切换背景时,如果从自定义图片切走,清除纹理缓存
|
||||
if !self.settings.bg_type.has_background() || !matches!(self.settings.bg_type, BgType::Custom(_)) {
|
||||
self.custom_texture = None;
|
||||
}
|
||||
}
|
||||
|
||||
if action.toggle_theme {
|
||||
@@ -285,4 +364,4 @@ let action = crate::reader::reading_view(
|
||||
self.save_reading_position();
|
||||
self.save_settings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use eframe::egui;
|
||||
use crate::book::Book;
|
||||
use crate::style::{StyleProfile, TextAlignment};
|
||||
use crate::theme::{self, Theme};
|
||||
use crate::theme::{self, BgType, Theme};
|
||||
|
||||
pub fn recalculate_pages(book: &mut Book, font_size: f32, line_height: f32, panel_width: f32, panel_height: f32) {
|
||||
let char_width = font_size * 0.6;
|
||||
@@ -25,7 +25,7 @@ pub struct ReaderAction {
|
||||
pub go_back: bool,
|
||||
pub toggle_theme: bool,
|
||||
pub toggle_bookmark: bool,
|
||||
pub toggle_kraft_bg: bool,
|
||||
pub switch_bg: Option<BgType>,
|
||||
pub switch_to_profile: Option<String>,
|
||||
pub page_next: bool,
|
||||
pub page_prev: bool,
|
||||
@@ -39,7 +39,7 @@ pub fn reading_view(
|
||||
sidebar_open: &mut bool,
|
||||
style: &mut StyleProfile,
|
||||
theme: &Theme,
|
||||
use_kraft_bg: bool,
|
||||
bg_type: BgType,
|
||||
_file_path: &str,
|
||||
profile_names: &[String],
|
||||
) -> ReaderAction {
|
||||
@@ -47,7 +47,7 @@ pub fn reading_view(
|
||||
go_back: false,
|
||||
toggle_theme: false,
|
||||
toggle_bookmark: false,
|
||||
toggle_kraft_bg: false,
|
||||
switch_bg: None,
|
||||
switch_to_profile: None,
|
||||
page_next: false,
|
||||
page_prev: false,
|
||||
@@ -108,10 +108,17 @@ pub fn reading_view(
|
||||
}
|
||||
}
|
||||
});
|
||||
let kraft_icon = if use_kraft_bg { "📄" } else { "📋" };
|
||||
if ui.button(kraft_icon).on_hover_text("牛皮纸背景").clicked() {
|
||||
action.toggle_kraft_bg = true;
|
||||
egui::ComboBox::from_id_salt("bg_type_selector")
|
||||
.width(100.0)
|
||||
.selected_text(bg_type.label())
|
||||
.show_ui(ui, |ui| {
|
||||
for &label in BgType::ALL.iter() {
|
||||
let selected = bg_type.label() == label;
|
||||
if ui.selectable_label(selected, label).clicked() {
|
||||
action.switch_bg = Some(theme::BgType::from_label(label));
|
||||
}
|
||||
}
|
||||
});
|
||||
if ui.button("☰").on_hover_text("打开/关闭目录").clicked() {
|
||||
*sidebar_open = !*sidebar_open;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ fn hash(x: u32, y: u32) -> u32 {
|
||||
}
|
||||
|
||||
fn paper_noise(x: u32, y: u32) -> u8 {
|
||||
// Combine multiple hash values for more natural-looking noise
|
||||
let n1 = hash(x, y);
|
||||
let n2 = hash(x.wrapping_add(137), y.wrapping_add(251));
|
||||
let n3 = hash(x.wrapping_mul(7), y.wrapping_mul(13));
|
||||
@@ -17,31 +16,73 @@ fn paper_noise(x: u32, y: u32) -> u8 {
|
||||
pub fn generate_kraft_paper(ctx: &egui::Context) -> egui::TextureHandle {
|
||||
let size = 128usize;
|
||||
let mut pixels = Vec::with_capacity(size * size);
|
||||
|
||||
for y in 0..size {
|
||||
for x in 0..size {
|
||||
let n = paper_noise(x as u32, y as u32);
|
||||
// Warm brown-beige base with slight variation
|
||||
let r = 212u8.wrapping_add(n);
|
||||
let g = 194u8.wrapping_add(n);
|
||||
let b = 168u8.wrapping_add(n);
|
||||
pixels.push(egui::Color32::from_rgb(r, g, b));
|
||||
}
|
||||
}
|
||||
|
||||
let image = egui::ColorImage {
|
||||
size: [size, size],
|
||||
pixels,
|
||||
};
|
||||
let image = egui::ColorImage { size: [size, size], pixels };
|
||||
ctx.load_texture("kraft_paper", image, Default::default())
|
||||
}
|
||||
|
||||
/// 稿纸:浅黄色 + 蓝色横线 + 红色竖线
|
||||
pub fn generate_manuscript(ctx: &egui::Context) -> egui::TextureHandle {
|
||||
let size = 256usize;
|
||||
let mut pixels = Vec::with_capacity(size * size);
|
||||
for y in 0..size {
|
||||
for x in 0..size {
|
||||
// 浅黄色基底
|
||||
let (r, g, b) = (245u8, 230u8, 195u8);
|
||||
// 横线:每 16 像素一条蓝色虚线
|
||||
let is_hline = y % 16 < 2 && x > 8 && x < size - 8;
|
||||
// 竖线:居中的红色引导线
|
||||
let is_vline = x == size / 2 && y > 16 && y < size - 16;
|
||||
let pixel = if is_vline {
|
||||
egui::Color32::from_rgb(220, 50, 50)
|
||||
} else if is_hline {
|
||||
egui::Color32::from_rgb(100, 100, 200)
|
||||
} else {
|
||||
egui::Color32::from_rgb(r, g, b)
|
||||
};
|
||||
pixels.push(pixel);
|
||||
}
|
||||
}
|
||||
let image = egui::ColorImage { size: [size, size], pixels };
|
||||
ctx.load_texture("manuscript", image, Default::default())
|
||||
}
|
||||
|
||||
/// 作文纸:浅绿色 + 横线网格
|
||||
pub fn generate_composition(ctx: &egui::Context) -> egui::TextureHandle {
|
||||
let size = 256usize;
|
||||
let mut pixels = Vec::with_capacity(size * size);
|
||||
for y in 0..size {
|
||||
for x in 0..size {
|
||||
// 浅绿色基底
|
||||
let (r, g, b) = (220u8, 235u8, 210u8);
|
||||
// 横线网格:每 16 像素一条灰色线
|
||||
let is_grid = (y % 16 < 1) || (x % 64 < 1);
|
||||
let pixel = if is_grid {
|
||||
egui::Color32::from_rgb(180, 180, 180)
|
||||
} else {
|
||||
egui::Color32::from_rgb(r, g, b)
|
||||
};
|
||||
pixels.push(pixel);
|
||||
}
|
||||
}
|
||||
let image = egui::ColorImage { size: [size, size], pixels };
|
||||
ctx.load_texture("composition", image, Default::default())
|
||||
}
|
||||
|
||||
pub fn draw_tiled_bg(
|
||||
painter: &egui::Painter,
|
||||
rect: egui::Rect,
|
||||
texture: &egui::TextureHandle,
|
||||
) {
|
||||
let tile_size = 128.0f32;
|
||||
let tile_size = 256.0f32;
|
||||
let mut ty = rect.min.y;
|
||||
while ty < rect.max.y {
|
||||
let mut tx = rect.min.x;
|
||||
|
||||
48
src/theme.rs
48
src/theme.rs
@@ -2,6 +2,50 @@ use eframe::egui;
|
||||
use eframe::egui::{Color32, CornerRadius, Stroke, Style, Visuals};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// 背景类型
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum BgType {
|
||||
None,
|
||||
Kraft,
|
||||
Manuscript,
|
||||
Composition,
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl Default for BgType {
|
||||
fn default() -> Self {
|
||||
BgType::None
|
||||
}
|
||||
}
|
||||
|
||||
impl BgType {
|
||||
pub const ALL: [&'static str; 5] = ["无", "牛皮纸", "稿纸", "作文纸", "自定义图片"];
|
||||
|
||||
pub fn label(&self) -> &str {
|
||||
match self {
|
||||
BgType::None => "无",
|
||||
BgType::Kraft => "牛皮纸",
|
||||
BgType::Manuscript => "稿纸",
|
||||
BgType::Composition => "作文纸",
|
||||
BgType::Custom(_) => "自定义图片",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_label(label: &str) -> Self {
|
||||
match label {
|
||||
"牛皮纸" => BgType::Kraft,
|
||||
"稿纸" => BgType::Manuscript,
|
||||
"作文纸" => BgType::Composition,
|
||||
"自定义图片" => BgType::Custom(String::new()),
|
||||
_ => BgType::None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_background(&self) -> bool {
|
||||
!matches!(self, BgType::None)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Theme {
|
||||
Light,
|
||||
@@ -170,7 +214,7 @@ pub fn create_style(theme: &Theme) -> Style {
|
||||
pub struct Settings {
|
||||
pub font_size: f32,
|
||||
pub theme: Theme,
|
||||
pub use_kraft_bg: bool,
|
||||
pub bg_type: BgType,
|
||||
pub active_profile: String,
|
||||
pub profiles: Vec<crate::style::StyleProfile>,
|
||||
pub recent_files: Vec<String>,
|
||||
@@ -184,7 +228,7 @@ impl Default for Settings {
|
||||
Self {
|
||||
font_size: 20.0,
|
||||
theme: Theme::Light,
|
||||
use_kraft_bg: false,
|
||||
bg_type: BgType::None,
|
||||
active_profile: "Kindle 默认".into(),
|
||||
profiles: crate::style::StyleProfile::presets(),
|
||||
recent_files: Vec::new(),
|
||||
|
||||
Reference in New Issue
Block a user