font browser
Migrate clear-typeface-interface to clear-ui framework
.gitignore | 1 +
Cargo.lock | 3534 +++++-----------------------------------------
Cargo.toml | 12 +-
src/main.rs | 1385 ++++++++++++++----
src/pages.rs | 68 +
src/pages/browse.rs | 326 -----
src/pages/details.rs | 203 ---
src/pages/keybindings.rs | 105 --
src/pages/mod.rs | 67 -
src/pages/preview.rs | 216 ---
10 files changed, 1532 insertions(+), 4385 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/Cargo.lock b/Cargo.lock
index 0ccc523..2391026 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,93 +2,12 @@
# It is not intended for manual editing.
version = 4
-[[package]]
-name = "ab_glyph"
-version = "0.2.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2"
-dependencies = [
- "ab_glyph_rasterizer",
- "owned_ttf_parser",
-]
-
-[[package]]
-name = "ab_glyph_rasterizer"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
-
[[package]]
name = "adler2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
-[[package]]
-name = "ahash"
-version = "0.8.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
-dependencies = [
- "cfg-if",
- "getrandom 0.3.4",
- "once_cell",
- "version_check",
- "zerocopy",
-]
-
-[[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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd"
-dependencies = [
- "android-properties",
- "bitflags 2.11.1",
- "cc",
- "jni",
- "libc",
- "log",
- "ndk",
- "ndk-context",
- "ndk-sys",
- "num_enum",
- "thiserror 2.0.18",
-]
-
-[[package]]
-name = "android-build"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cac4c64175d504608cf239756339c07f6384a476f97f20a7043f92920b0b8fd"
-dependencies = [
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "android-properties"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04"
-
[[package]]
name = "android_system_properties"
version = "0.1.5"
@@ -98,29 +17,6 @@ dependencies = [
"libc",
]
-[[package]]
-name = "anyhow"
-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 = "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"
@@ -133,21 +29,6 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
-[[package]]
-name = "as-raw-xcb-connection"
-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"
@@ -157,192 +38,12 @@ dependencies = [
"libloading",
]
-[[package]]
-name = "async-broadcast"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
-dependencies = [
- "event-listener",
- "event-listener-strategy",
- "futures-core",
- "pin-project-lite",
-]
-
-[[package]]
-name = "async-channel"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
-dependencies = [
- "concurrent-queue",
- "event-listener-strategy",
- "futures-core",
- "pin-project-lite",
-]
-
-[[package]]
-name = "async-executor"
-version = "1.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a"
-dependencies = [
- "async-task",
- "concurrent-queue",
- "fastrand",
- "futures-lite",
- "pin-project-lite",
- "slab",
-]
-
-[[package]]
-name = "async-io"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
-dependencies = [
- "autocfg",
- "cfg-if",
- "concurrent-queue",
- "futures-io",
- "futures-lite",
- "parking",
- "polling",
- "rustix 1.1.4",
- "slab",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "async-lock"
-version = "3.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
-dependencies = [
- "event-listener",
- "event-listener-strategy",
- "pin-project-lite",
-]
-
-[[package]]
-name = "async-process"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
-dependencies = [
- "async-channel",
- "async-io",
- "async-lock",
- "async-signal",
- "async-task",
- "blocking",
- "cfg-if",
- "event-listener",
- "futures-lite",
- "rustix 1.1.4",
-]
-
-[[package]]
-name = "async-recursion"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "async-signal"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485"
-dependencies = [
- "async-io",
- "async-lock",
- "atomic-waker",
- "cfg-if",
- "futures-core",
- "futures-io",
- "rustix 1.1.4",
- "signal-hook-registry",
- "slab",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "async-task"
-version = "4.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
-
-[[package]]
-name = "async-trait"
-version = "0.1.89"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "atomic-waker"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
-
[[package]]
name = "autocfg"
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 = "base64"
version = "0.22.1"
@@ -364,12 +65,6 @@ 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"
@@ -381,14 +76,8 @@ name = "bitflags"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
-
-[[package]]
-name = "bitstream-io"
-version = "4.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7eff00be299a18769011411c9def0d827e8f2d7bf0c3dbf53633147a8867fd1f"
dependencies = [
- "no_std_io2",
+ "serde_core",
]
[[package]]
@@ -397,43 +86,6 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
-[[package]]
-name = "block2"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
-dependencies = [
- "objc2 0.5.2",
-]
-
-[[package]]
-name = "block2"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
-dependencies = [
- "objc2 0.6.4",
-]
-
-[[package]]
-name = "blocking"
-version = "1.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
-dependencies = [
- "async-channel",
- "async-task",
- "futures-io",
- "futures-lite",
- "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"
@@ -460,12 +112,6 @@ dependencies = [
"syn",
]
-[[package]]
-name = "byteorder-lite"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
-
[[package]]
name = "bytes"
version = "1.11.1"
@@ -486,43 +132,18 @@ dependencies = [
"thiserror 1.0.69",
]
-[[package]]
-name = "calloop"
-version = "0.14.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7"
-dependencies = [
- "bitflags 2.11.1",
- "polling",
- "rustix 1.1.4",
- "slab",
- "tracing",
-]
-
[[package]]
name = "calloop-wayland-source"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20"
dependencies = [
- "calloop 0.13.0",
+ "calloop",
"rustix 0.38.44",
"wayland-backend",
"wayland-client",
]
-[[package]]
-name = "calloop-wayland-source"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa"
-dependencies = [
- "calloop 0.14.4",
- "rustix 1.1.4",
- "wayland-backend",
- "wayland-client",
-]
-
[[package]]
name = "cc"
version = "1.2.62"
@@ -530,8 +151,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
dependencies = [
"find-msvc-tools",
- "jobserver",
- "libc",
"shlex",
]
@@ -551,58 +170,51 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
name = "clear-typeface-interface"
version = "0.1.0"
dependencies = [
- "iced",
+ "bytemuck",
+ "calloop",
+ "calloop-wayland-source",
+ "clear-ui",
+ "glyphon",
+ "pollster",
+ "raw-window-handle",
+ "smithay-client-toolkit",
"tokio",
+ "wayland-client",
+ "wgpu",
+ "xkeysym",
]
[[package]]
-name = "clipboard-win"
-version = "5.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4"
+name = "clear-ui"
+version = "0.1.0"
dependencies = [
- "error-code",
+ "bytemuck",
+ "calloop",
+ "calloop-wayland-source",
+ "glyphon",
+ "libc",
+ "pollster",
+ "raw-window-handle",
+ "resvg",
+ "serde",
+ "serde_json",
+ "smithay-client-toolkit",
+ "tokio",
+ "wayland-backend",
+ "wayland-client",
+ "wayland-scanner",
+ "wgpu",
+ "xkeysym",
]
[[package]]
-name = "clipboard_macos"
-version = "0.1.1"
+name = "codespan-reporting"
+version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b7f4aaa047ba3c3630b080bb9860894732ff23e2aee290a418909aa6d5df38f"
+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
dependencies = [
- "objc2 0.5.2",
- "objc2-app-kit 0.2.2",
- "objc2-foundation 0.2.2",
-]
-
-[[package]]
-name = "clipboard_wayland"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "003f886bc4e2987729d10c1db3424e7f80809f3fc22dbc16c685738887cb37b8"
-dependencies = [
- "smithay-clipboard",
-]
-
-[[package]]
-name = "clipboard_x11"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd63e33452ffdafd39924c4f05a5dd1e94db646c779c6bd59148a3d95fff5ad4"
-dependencies = [
- "thiserror 2.0.18",
- "x11rb",
-]
-
-[[package]]
-name = "codespan-reporting"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81"
-dependencies = [
- "serde",
- "termcolor",
- "unicode-width",
+ "termcolor",
+ "unicode-width",
]
[[package]]
@@ -611,16 +223,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
-[[package]]
-name = "combine"
-version = "4.6.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
-dependencies = [
- "bytes",
- "memchr",
-]
-
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@@ -640,35 +242,12 @@ dependencies = [
"libc",
]
-[[package]]
-name = "core-foundation"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
-[[package]]
-name = "core-graphics"
-version = "0.23.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation 0.9.4",
- "core-graphics-types 0.1.3",
- "foreign-types",
- "libc",
-]
-
[[package]]
name = "core-graphics-types"
version = "0.1.3"
@@ -676,48 +255,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
dependencies = [
"bitflags 1.3.2",
- "core-foundation 0.9.4",
- "libc",
-]
-
-[[package]]
-name = "core-graphics-types"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb"
-dependencies = [
- "bitflags 2.11.1",
- "core-foundation 0.10.1",
+ "core-foundation",
"libc",
]
-[[package]]
-name = "core_maths"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30"
-dependencies = [
- "libm",
-]
-
[[package]]
name = "cosmic-text"
-version = "0.15.0"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "173852283a9a57a3cbe365d86e74dc428a09c50421477d5ad6fe9d9509e37737"
+checksum = "59fd57d82eb4bfe7ffa9b1cec0c05e2fd378155b47f255a67983cb4afe0e80c2"
dependencies = [
"bitflags 2.11.1",
"fontdb",
- "harfrust",
- "linebender_resource_handle",
"log",
"rangemap",
+ "rayon",
"rustc-hash 1.1.0",
+ "rustybuzz 0.14.1",
"self_cell",
- "skrifa 0.37.0",
- "smol_str",
"swash",
"sys-locale",
+ "ttf-parser 0.21.1",
"unicode-bidi",
"unicode-linebreak",
"unicode-script",
@@ -758,34 +316,6 @@ version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
-[[package]]
-name = "crunchy"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
-
-[[package]]
-name = "cryoglyph"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08bc795bdbccdbd461736fb163930a009da6597b226d6f6fce33e7a8eb6ec519"
-dependencies = [
- "cosmic-text",
- "etagere",
- "lru",
- "rustc-hash 2.1.2",
- "wgpu",
-]
-
-[[package]]
-name = "ctor"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83cf0d42651b16c6dfe68685716d18480d18a9c39c62d76e8cf3eb6ed5d8bcbf"
-dependencies = [
- "dtor",
-]
-
[[package]]
name = "cursor-icon"
version = "1.2.0"
@@ -798,22 +328,6 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376"
-[[package]]
-name = "dispatch"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
-
-[[package]]
-name = "dispatch2"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
-dependencies = [
- "bitflags 2.11.1",
- "objc2 0.6.4",
-]
-
[[package]]
name = "dlib"
version = "0.5.3"
@@ -838,71 +352,12 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
-[[package]]
-name = "dpi"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
-
-[[package]]
-name = "dtor"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edf234dd1594d6dd434a8fb8cada51ddbbc593e40e4a01556a0b31c62da2775b"
-
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
-[[package]]
-name = "endi"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
-
-[[package]]
-name = "enumflags2"
-version = "0.7.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
-dependencies = [
- "enumflags2_derive",
- "serde",
-]
-
-[[package]]
-name = "enumflags2_derive"
-version = "0.7.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[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"
@@ -919,12 +374,6 @@ dependencies = [
"windows-sys 0.61.2",
]
-[[package]]
-name = "error-code"
-version = "3.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
-
[[package]]
name = "etagere"
version = "0.2.15"
@@ -944,54 +393,6 @@ dependencies = [
"num-traits",
]
-[[package]]
-name = "event-listener"
-version = "5.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
-dependencies = [
- "concurrent-queue",
- "parking",
- "pin-project-lite",
-]
-
-[[package]]
-name = "event-listener-strategy"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
-dependencies = [
- "event-listener",
- "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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
-
-[[package]]
-name = "fax"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a"
-
[[package]]
name = "fdeflate"
version = "0.3.7"
@@ -1029,26 +430,11 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
-[[package]]
-name = "foldhash"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
-
-[[package]]
-name = "font-types"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39a654f404bbcbd48ea58c617c2993ee91d1cb63727a37bf2323a4edeed1b8c5"
-dependencies = [
- "bytemuck",
-]
-
[[package]]
name = "font-types"
-version = "0.11.3"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7"
+checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492"
dependencies = [
"bytemuck",
]
@@ -1059,21 +445,21 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646"
dependencies = [
- "roxmltree",
+ "roxmltree 0.20.0",
]
[[package]]
name = "fontdb"
-version = "0.23.0"
+version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905"
+checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3"
dependencies = [
"fontconfig-parser",
"log",
- "memmap2",
+ "memmap2 0.9.10",
"slotmap",
"tinyvec",
- "ttf-parser",
+ "ttf-parser 0.20.0",
]
[[package]]
@@ -1103,84 +489,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
-[[package]]
-name = "futures"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
-dependencies = [
- "futures-core",
- "futures-sink",
-]
-
[[package]]
name = "futures-core"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
-[[package]]
-name = "futures-executor"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
-
-[[package]]
-name = "futures-lite"
-version = "2.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
-dependencies = [
- "fastrand",
- "futures-core",
- "futures-io",
- "parking",
- "pin-project-lite",
-]
-
-[[package]]
-name = "futures-macro"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
-
[[package]]
name = "futures-task"
version = "0.3.32"
@@ -1193,52 +507,12 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
- "futures-channel",
"futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
"futures-task",
- "memchr",
"pin-project-lite",
"slab",
]
-[[package]]
-name = "gethostname"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
-dependencies = [
- "rustix 1.1.4",
- "windows-link",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
-dependencies = [
- "cfg-if",
- "libc",
- "r-efi 5.3.0",
- "wasip2",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
-dependencies = [
- "cfg-if",
- "libc",
- "r-efi 6.0.0",
- "wasip2",
- "wasip3",
-]
-
[[package]]
name = "gif"
version = "0.13.3"
@@ -1249,16 +523,6 @@ dependencies = [
"weezl",
]
-[[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"
@@ -1270,12 +534,6 @@ dependencies = [
"xml-rs",
]
-[[package]]
-name = "glam"
-version = "0.25.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "151665d9be52f9bb40fc7966565d39666f2d1e69233571b71b87791c7e0528b3"
-
[[package]]
name = "glow"
version = "0.16.0"
@@ -1297,6 +555,19 @@ dependencies = [
"gl_generator",
]
+[[package]]
+name = "glyphon"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc83cc30ed66a0a9e77b7974c91360a13cad5e7ab65aa51e299c383749a018ab"
+dependencies = [
+ "cosmic-text",
+ "etagere",
+ "lru",
+ "rustc-hash 2.1.2",
+ "wgpu",
+]
+
[[package]]
name = "gpu-alloc"
version = "0.6.0"
@@ -1325,7 +596,7 @@ dependencies = [
"log",
"presser",
"thiserror 1.0.69",
- "windows 0.58.0",
+ "windows",
]
[[package]]
@@ -1348,57 +619,13 @@ dependencies = [
"bitflags 2.11.1",
]
-[[package]]
-name = "guillotiere"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782"
-dependencies = [
- "euclid",
- "svg_fmt",
-]
-
-[[package]]
-name = "half"
-version = "2.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
-dependencies = [
- "cfg-if",
- "crunchy",
- "num-traits",
- "zerocopy",
-]
-
-[[package]]
-name = "harfrust"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92c020db12c71d8a12a3fe7607873cade3a01a6287e29d540c8723276221b9d8"
-dependencies = [
- "bitflags 2.11.1",
- "bytemuck",
- "core_maths",
- "read-fonts 0.35.0",
- "smallvec",
-]
-
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
- "foldhash 0.1.5",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
-dependencies = [
- "foldhash 0.2.0",
+ "foldhash",
]
[[package]]
@@ -1419,259 +646,17 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
-[[package]]
-name = "hex"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
-
[[package]]
name = "hexf-parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
-[[package]]
-name = "iced"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "000e01026c93ba643f8357a3db3ada0e6555265a377f6f9291c472f6dd701fb3"
-dependencies = [
- "iced_core",
- "iced_debug",
- "iced_futures",
- "iced_renderer",
- "iced_runtime",
- "iced_widget",
- "iced_winit",
- "image",
- "thiserror 2.0.18",
-]
-
-[[package]]
-name = "iced_core"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91ab1937d699403e7e69252ae743a902bcee9f4ab2052cc4c9a46fcf34729d85"
-dependencies = [
- "bitflags 2.11.1",
- "bytes",
- "glam",
- "lilt",
- "log",
- "num-traits",
- "rustc-hash 2.1.2",
- "smol_str",
- "thiserror 2.0.18",
- "web-time",
-]
-
-[[package]]
-name = "iced_debug"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25035ab0215a620e53f4103e36fc4e59a1fb2817e4bfc38a30ad27b4202ea0be"
-dependencies = [
- "iced_core",
- "iced_futures",
- "log",
-]
-
-[[package]]
-name = "iced_futures"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c0c85ccad42dfbec7293c36c018af0ea0dbcc52d137a4a9a0b0f6822a3fdf0a"
-dependencies = [
- "futures",
- "iced_core",
- "log",
- "rustc-hash 2.1.2",
- "tokio",
- "wasm-bindgen-futures",
- "wasmtimer",
-]
-
-[[package]]
-name = "iced_graphics"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "234ca1c2cec4155055f68fa5fad1b5242c496ac8238d80a259bca382fb44a102"
-dependencies = [
- "bitflags 2.11.1",
- "bytemuck",
- "cosmic-text",
- "half",
- "iced_core",
- "iced_futures",
- "image",
- "kamadak-exif",
- "log",
- "raw-window-handle",
- "rustc-hash 2.1.2",
- "thiserror 2.0.18",
- "unicode-segmentation",
-]
-
-[[package]]
-name = "iced_program"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6dfafec2947cda688d8eb00dac337ba11aa60f9ef6335aed343e189d26e4a673"
-dependencies = [
- "iced_graphics",
- "iced_runtime",
-]
-
-[[package]]
-name = "iced_renderer"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "250cc0802408e8c077986ec56c7d07c65f423ee658a4b9fd795a1f2aae5dac05"
-dependencies = [
- "iced_graphics",
- "iced_tiny_skia",
- "iced_wgpu",
- "log",
- "thiserror 2.0.18",
-]
-
-[[package]]
-name = "iced_runtime"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1889b819ce4c06674183242e336c8d49465665441396914dc07cc86f44fa8d4"
-dependencies = [
- "bytes",
- "iced_core",
- "iced_futures",
- "raw-window-handle",
- "thiserror 2.0.18",
-]
-
-[[package]]
-name = "iced_tiny_skia"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe0acf8b75a3bc914aff5f2329fdffc1b36eeaea29dda0e4bd232f1c62e9cc3d"
-dependencies = [
- "bytemuck",
- "cosmic-text",
- "iced_debug",
- "iced_graphics",
- "kurbo 0.10.4",
- "log",
- "resvg",
- "rustc-hash 2.1.2",
- "softbuffer",
- "tiny-skia",
-]
-
-[[package]]
-name = "iced_wgpu"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff144a999b0ca0f8a10257934500060240825c42e950ec0ebee9c8ae30561c13"
-dependencies = [
- "bitflags 2.11.1",
- "bytemuck",
- "cryoglyph",
- "futures",
- "glam",
- "guillotiere",
- "iced_debug",
- "iced_graphics",
- "log",
- "resvg",
- "rustc-hash 2.1.2",
- "thiserror 2.0.18",
- "wgpu",
-]
-
-[[package]]
-name = "iced_widget"
-version = "0.14.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1596afa0d3109c2618e8bc12bae6c11d3064df8f95c42dfce570397dbe957ab"
-dependencies = [
- "iced_renderer",
- "log",
- "num-traits",
- "rustc-hash 2.1.2",
- "thiserror 2.0.18",
- "unicode-segmentation",
-]
-
-[[package]]
-name = "iced_winit"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b7dbedc47562d1de3b9707d939f678b88c382004b7ab5a18f7a7dd723162d75"
-dependencies = [
- "iced_debug",
- "iced_program",
- "log",
- "mundy",
- "rustc-hash 2.1.2",
- "thiserror 2.0.18",
- "tracing",
- "wasm-bindgen-futures",
- "web-sys",
- "window_clipboard",
- "winit",
-]
-
-[[package]]
-name = "id-arena"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
-
-[[package]]
-name = "image"
-version = "0.25.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104"
-dependencies = [
- "bytemuck",
- "byteorder-lite",
- "color_quant",
- "exr",
- "gif 0.14.2",
- "image-webp",
- "moxcms",
- "num-traits",
- "png 0.18.1",
- "qoi",
- "ravif",
- "rayon",
- "rgb",
- "tiff",
- "zune-core 0.5.1",
- "zune-jpeg 0.5.15",
-]
-
-[[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 = "imagesize"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285"
-
-[[package]]
-name = "imgref"
-version = "1.12.1"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40fac9d56ed6437b198fddba683305e8e2d651aa42647f00f5ae542e7f5c94a2"
+checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
[[package]]
name = "indexmap"
@@ -1679,920 +664,267 @@ version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
- "equivalent",
- "hashbrown 0.17.1",
- "serde",
- "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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
-
-[[package]]
-name = "jni"
-version = "0.22.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
-dependencies = [
- "cfg-if",
- "combine",
- "jni-macros",
- "jni-sys 0.4.1",
- "log",
- "simd_cesu8",
- "thiserror 2.0.18",
- "walkdir",
- "windows-link",
-]
-
-[[package]]
-name = "jni-macros"
-version = "0.22.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
-dependencies = [
- "proc-macro2",
- "quote",
- "rustc_version",
- "simd_cesu8",
- "syn",
-]
-
-[[package]]
-name = "jni-sys"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258"
-dependencies = [
- "jni-sys 0.4.1",
-]
-
-[[package]]
-name = "jni-sys"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
-dependencies = [
- "jni-sys-macros",
-]
-
-[[package]]
-name = "jni-sys-macros"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
-name = "jobserver"
-version = "0.1.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
-dependencies = [
- "getrandom 0.3.4",
- "libc",
-]
-
-[[package]]
-name = "js-sys"
-version = "0.3.98"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08"
-dependencies = [
- "cfg-if",
- "futures-util",
- "once_cell",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "kamadak-exif"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1130d80c7374efad55a117d715a3af9368f0fa7a2c54573afc15a188cd984837"
-dependencies = [
- "mutate_once",
-]
-
-[[package]]
-name = "khronos-egl"
-version = "6.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76"
-dependencies = [
- "libc",
- "libloading",
- "pkg-config",
-]
-
-[[package]]
-name = "khronos_api"
-version = "3.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
-
-[[package]]
-name = "kurbo"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1618d4ebd923e97d67e7cd363d80aef35fe961005cbbbb3d2dad8bdd1bc63440"
-dependencies = [
- "arrayvec",
- "smallvec",
-]
-
-[[package]]
-name = "kurbo"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62"
-dependencies = [
- "arrayvec",
- "euclid",
- "smallvec",
-]
-
-[[package]]
-name = "leb128fmt"
-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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
-dependencies = [
- "cfg-if",
- "windows-link",
-]
-
-[[package]]
-name = "libm"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
-
-[[package]]
-name = "libredox"
-version = "0.1.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c"
-dependencies = [
- "bitflags 2.11.1",
- "libc",
- "plain",
- "redox_syscall 0.7.5",
-]
-
-[[package]]
-name = "lilt"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f67562e5eff6b20553fa9be1c503356768420994e28f67e3eafe6f41910e57ad"
-dependencies = [
- "web-time",
-]
-
-[[package]]
-name = "linebender_resource_handle"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4"
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.4.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
-
-[[package]]
-name = "litrs"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
-
-[[package]]
-name = "lock_api"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
-dependencies = [
- "scopeguard",
-]
-
-[[package]]
-name = "log"
-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 = "lru"
-version = "0.16.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
-
-[[package]]
-name = "malloc_buf"
-version = "0.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
-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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
-
-[[package]]
-name = "memmap2"
-version = "0.9.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "memoffset"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "metal"
-version = "0.32.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605"
-dependencies = [
- "bitflags 2.11.1",
- "block",
- "core-graphics-types 0.2.0",
- "foreign-types",
- "log",
- "objc",
- "paste",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.8.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
-dependencies = [
- "adler2",
- "simd-adler32",
-]
-
-[[package]]
-name = "mio"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
-dependencies = [
- "libc",
- "wasi",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "moxcms"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b"
-dependencies = [
- "num-traits",
- "pxfm",
-]
-
-[[package]]
-name = "mundy"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f32eb0db40f2df2bcfb05c93b8f73938d4c26ce9ac8881f1df0c8d3296921a73"
-dependencies = [
- "android-build",
- "async-io",
- "cfg-if",
- "dispatch",
- "futures-channel",
- "futures-lite",
- "jni",
- "ndk-context",
- "objc2 0.6.4",
- "objc2-app-kit 0.3.2",
- "objc2-foundation 0.3.2",
- "pin-project-lite",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "windows 0.62.2",
- "zbus",
-]
-
-[[package]]
-name = "mutate_once"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13d2233c9842d08cfe13f9eac96e207ca6a2ea10b80259ebe8ad0268be27d2af"
-
-[[package]]
-name = "naga"
-version = "27.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8"
-dependencies = [
- "arrayvec",
- "bit-set",
- "bitflags 2.11.1",
- "cfg-if",
- "cfg_aliases",
- "codespan-reporting",
- "half",
- "hashbrown 0.16.1",
- "hexf-parse",
- "indexmap",
- "libm",
- "log",
- "num-traits",
- "once_cell",
- "rustc-hash 1.1.0",
- "spirv",
- "thiserror 2.0.18",
- "unicode-ident",
-]
-
-[[package]]
-name = "ndk"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4"
-dependencies = [
- "bitflags 2.11.1",
- "jni-sys 0.3.1",
- "log",
- "ndk-sys",
- "num_enum",
- "raw-window-handle",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "ndk-context"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
-
-[[package]]
-name = "ndk-sys"
-version = "0.6.0+11769913"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873"
-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 = "no_std_io2"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003"
-dependencies = [
- "memchr",
-]
-
-[[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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
-dependencies = [
- "autocfg",
- "libm",
-]
-
-[[package]]
-name = "num_enum"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26"
-dependencies = [
- "num_enum_derive",
- "rustversion",
-]
-
-[[package]]
-name = "num_enum_derive"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "objc"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
-dependencies = [
- "malloc_buf",
+ "equivalent",
+ "hashbrown 0.17.1",
]
[[package]]
-name = "objc-sys"
-version = "0.3.5"
+name = "itoa"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
+checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
-name = "objc2"
-version = "0.5.2"
+name = "jni-sys"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
+checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258"
dependencies = [
- "objc-sys",
- "objc2-encode",
+ "jni-sys 0.4.1",
]
[[package]]
-name = "objc2"
-version = "0.6.4"
+name = "jni-sys"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f"
+checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
dependencies = [
- "objc2-encode",
+ "jni-sys-macros",
]
[[package]]
-name = "objc2-app-kit"
-version = "0.2.2"
+name = "jni-sys-macros"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
+checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
dependencies = [
- "bitflags 2.11.1",
- "block2 0.5.1",
- "libc",
- "objc2 0.5.2",
- "objc2-core-data 0.2.2",
- "objc2-core-image 0.2.2",
- "objc2-foundation 0.2.2",
- "objc2-quartz-core 0.2.2",
+ "quote",
+ "syn",
]
[[package]]
-name = "objc2-app-kit"
+name = "jpeg-decoder"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c"
-dependencies = [
- "bitflags 2.11.1",
- "block2 0.6.2",
- "libc",
- "objc2 0.6.4",
- "objc2-cloud-kit 0.3.2",
- "objc2-core-data 0.3.2",
- "objc2-core-foundation",
- "objc2-core-graphics",
- "objc2-core-image 0.3.2",
- "objc2-core-text",
- "objc2-core-video",
- "objc2-foundation 0.3.2",
- "objc2-quartz-core 0.3.2",
-]
+checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07"
[[package]]
-name = "objc2-cloud-kit"
-version = "0.2.2"
+name = "js-sys"
+version = "0.3.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
+checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08"
dependencies = [
- "bitflags 2.11.1",
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-core-location",
- "objc2-foundation 0.2.2",
+ "cfg-if",
+ "futures-util",
+ "once_cell",
+ "wasm-bindgen",
]
[[package]]
-name = "objc2-cloud-kit"
-version = "0.3.2"
+name = "khronos-egl"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c"
+checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76"
dependencies = [
- "bitflags 2.11.1",
- "objc2 0.6.4",
- "objc2-foundation 0.3.2",
+ "libc",
+ "libloading",
+ "pkg-config",
]
[[package]]
-name = "objc2-contacts"
-version = "0.2.2"
+name = "khronos_api"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
-dependencies = [
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
-]
+checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
-name = "objc2-core-data"
-version = "0.2.2"
+name = "kurbo"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
+checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62"
dependencies = [
- "bitflags 2.11.1",
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
+ "arrayvec",
+ "euclid",
+ "smallvec",
]
[[package]]
-name = "objc2-core-data"
-version = "0.3.2"
+name = "libc"
+version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa"
-dependencies = [
- "bitflags 2.11.1",
- "objc2 0.6.4",
- "objc2-foundation 0.3.2",
-]
+checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
-name = "objc2-core-foundation"
-version = "0.3.2"
+name = "libloading"
+version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
+checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
dependencies = [
- "bitflags 2.11.1",
- "dispatch2",
- "objc2 0.6.4",
+ "cfg-if",
+ "windows-link",
]
[[package]]
-name = "objc2-core-graphics"
-version = "0.3.2"
+name = "libm"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807"
-dependencies = [
- "bitflags 2.11.1",
- "dispatch2",
- "objc2 0.6.4",
- "objc2-core-foundation",
- "objc2-io-surface",
-]
+checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
-name = "objc2-core-image"
-version = "0.2.2"
+name = "linux-raw-sys"
+version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
-dependencies = [
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
- "objc2-metal",
-]
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
-name = "objc2-core-image"
-version = "0.3.2"
+name = "linux-raw-sys"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006"
-dependencies = [
- "objc2 0.6.4",
- "objc2-foundation 0.3.2",
-]
+checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
[[package]]
-name = "objc2-core-location"
-version = "0.2.2"
+name = "litrs"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
-dependencies = [
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-contacts",
- "objc2-foundation 0.2.2",
-]
+checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
[[package]]
-name = "objc2-core-text"
-version = "0.3.2"
+name = "lock_api"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
+checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
- "bitflags 2.11.1",
- "objc2 0.6.4",
- "objc2-core-foundation",
- "objc2-core-graphics",
+ "scopeguard",
]
[[package]]
-name = "objc2-core-video"
-version = "0.3.2"
+name = "log"
+version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6"
-dependencies = [
- "bitflags 2.11.1",
- "objc2 0.6.4",
- "objc2-core-foundation",
- "objc2-core-graphics",
- "objc2-io-surface",
-]
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
-name = "objc2-encode"
-version = "4.1.0"
+name = "lru"
+version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
+checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
[[package]]
-name = "objc2-foundation"
-version = "0.2.2"
+name = "malloc_buf"
+version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
+checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
dependencies = [
- "bitflags 2.11.1",
- "block2 0.5.1",
- "dispatch",
"libc",
- "objc2 0.5.2",
]
[[package]]
-name = "objc2-foundation"
-version = "0.3.2"
+name = "memchr"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+
+[[package]]
+name = "memmap2"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
+checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed"
dependencies = [
- "bitflags 2.11.1",
- "block2 0.6.2",
"libc",
- "objc2 0.6.4",
- "objc2-core-foundation",
]
[[package]]
-name = "objc2-io-surface"
-version = "0.3.2"
+name = "memmap2"
+version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
+checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3"
dependencies = [
- "bitflags 2.11.1",
- "objc2 0.6.4",
- "objc2-core-foundation",
+ "libc",
]
[[package]]
-name = "objc2-link-presentation"
-version = "0.2.2"
+name = "metal"
+version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
+checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e"
dependencies = [
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-app-kit 0.2.2",
- "objc2-foundation 0.2.2",
+ "bitflags 2.11.1",
+ "block",
+ "core-graphics-types",
+ "foreign-types",
+ "log",
+ "objc",
+ "paste",
]
[[package]]
-name = "objc2-metal"
-version = "0.2.2"
+name = "miniz_oxide"
+version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
+checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [
- "bitflags 2.11.1",
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
+ "adler2",
+ "simd-adler32",
]
[[package]]
-name = "objc2-quartz-core"
-version = "0.2.2"
+name = "mio"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
+checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
dependencies = [
- "bitflags 2.11.1",
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
- "objc2-metal",
+ "libc",
+ "wasi",
+ "windows-sys 0.61.2",
]
[[package]]
-name = "objc2-quartz-core"
-version = "0.3.2"
+name = "naga"
+version = "24.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
+checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e"
dependencies = [
+ "arrayvec",
+ "bit-set",
"bitflags 2.11.1",
- "objc2 0.6.4",
- "objc2-core-foundation",
- "objc2-foundation 0.3.2",
+ "cfg_aliases",
+ "codespan-reporting",
+ "hexf-parse",
+ "indexmap",
+ "log",
+ "rustc-hash 1.1.0",
+ "spirv",
+ "strum",
+ "termcolor",
+ "thiserror 2.0.18",
+ "unicode-xid",
]
[[package]]
-name = "objc2-symbols"
-version = "0.2.2"
+name = "ndk-sys"
+version = "0.5.0+25.2.9519653"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc"
+checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691"
dependencies = [
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
+ "jni-sys 0.3.1",
]
[[package]]
-name = "objc2-ui-kit"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
-dependencies = [
- "bitflags 2.11.1",
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-cloud-kit 0.2.2",
- "objc2-core-data 0.2.2",
- "objc2-core-image 0.2.2",
- "objc2-core-location",
- "objc2-foundation 0.2.2",
- "objc2-link-presentation",
- "objc2-quartz-core 0.2.2",
- "objc2-symbols",
- "objc2-uniform-type-identifiers",
- "objc2-user-notifications",
-]
-
-[[package]]
-name = "objc2-uniform-type-identifiers"
-version = "0.2.2"
+name = "num-traits"
+version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
+ "autocfg",
]
[[package]]
-name = "objc2-user-notifications"
-version = "0.2.2"
+name = "objc"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
+checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
dependencies = [
- "bitflags 2.11.1",
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-core-location",
- "objc2-foundation 0.2.2",
+ "malloc_buf",
]
[[package]]
@@ -2601,50 +933,15 @@ version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
-[[package]]
-name = "orbclient"
-version = "0.3.54"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a570f6bca41d29acb2139229a7c873ec99bc9a313bd10804081d89bfac8ff329"
-dependencies = [
- "libc",
- "libredox",
-]
-
[[package]]
name = "ordered-float"
-version = "5.3.0"
+version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e"
+checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
dependencies = [
"num-traits",
]
-[[package]]
-name = "ordered-stream"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
-dependencies = [
- "futures-core",
- "pin-project-lite",
-]
-
-[[package]]
-name = "owned_ttf_parser"
-version = "0.25.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b"
-dependencies = [
- "ttf-parser",
-]
-
-[[package]]
-name = "parking"
-version = "2.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
-
[[package]]
name = "parking_lot"
version = "0.12.5"
@@ -2663,7 +960,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall 0.5.18",
+ "redox_syscall",
"smallvec",
"windows-link",
]
@@ -2674,99 +971,31 @@ 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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
-
[[package]]
name = "pico-args"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
-[[package]]
-name = "pin-project"
-version = "1.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "piper"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1"
-dependencies = [
- "atomic-waker",
- "fastrand",
- "futures-io",
-]
-
[[package]]
name = "pkg-config"
version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
-
-[[package]]
-name = "plain"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
-
-[[package]]
-name = "png"
-version = "0.17.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
-dependencies = [
- "bitflags 1.3.2",
- "crc32fast",
- "fdeflate",
- "flate2",
- "miniz_oxide",
-]
+checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
[[package]]
name = "png"
-version = "0.18.1"
+version = "0.17.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61"
+checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
dependencies = [
- "bitflags 2.11.1",
+ "bitflags 1.3.2",
"crc32fast",
"fdeflate",
"flate2",
@@ -2788,28 +1017,10 @@ dependencies = [
]
[[package]]
-name = "portable-atomic"
-version = "1.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
-
-[[package]]
-name = "portable-atomic-util"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
-dependencies = [
- "portable-atomic",
-]
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.21"
+name = "pollster"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
-dependencies = [
- "zerocopy",
-]
+checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
[[package]]
name = "presser"
@@ -2817,25 +1028,6 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
-[[package]]
-name = "prettyplease"
-version = "0.2.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
-dependencies = [
- "proc-macro2",
- "syn",
-]
-
-[[package]]
-name = "proc-macro-crate"
-version = "3.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
-dependencies = [
- "toml_edit",
-]
-
[[package]]
name = "proc-macro2"
version = "1.0.106"
@@ -2850,40 +1042,6 @@ 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"
-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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
[[package]]
name = "quick-xml"
@@ -2903,47 +1061,6 @@ dependencies = [
"proc-macro2",
]
-[[package]]
-name = "r-efi"
-version = "5.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
-
-[[package]]
-name = "r-efi"
-version = "6.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
-
-[[package]]
-name = "rand"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
-dependencies = [
- "rand_chacha",
- "rand_core",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
-dependencies = [
- "ppv-lite86",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.9.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
-dependencies = [
- "getrandom 0.3.4",
-]
-
[[package]]
name = "range-alloc"
version = "0.1.5"
@@ -2956,56 +1073,6 @@ version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68"
-[[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",
- "rand_chacha",
- "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"
@@ -3034,32 +1101,12 @@ dependencies = [
[[package]]
name = "read-fonts"
-version = "0.35.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358"
-dependencies = [
- "bytemuck",
- "core_maths",
- "font-types 0.10.1",
-]
-
-[[package]]
-name = "read-fonts"
-version = "0.37.0"
+version = "0.22.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5"
+checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f"
dependencies = [
"bytemuck",
- "font-types 0.11.3",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
-dependencies = [
- "bitflags 1.3.2",
+ "font-types",
]
[[package]]
@@ -3071,15 +1118,6 @@ dependencies = [
"bitflags 2.11.1",
]
-[[package]]
-name = "redox_syscall"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b"
-dependencies = [
- "bitflags 2.11.1",
-]
-
[[package]]
name = "renderdoc-sys"
version = "1.1.0"
@@ -3088,19 +1126,19 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "resvg"
-version = "0.45.1"
+version = "0.41.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8928798c0a55e03c9ca6c4c6846f76377427d2c1e1f7e6de3c06ae57942df43"
+checksum = "c2327ced609dadeed3e9702fec3e6b2ddd208758a9268d13e06566c6101ba533"
dependencies = [
- "gif 0.13.3",
- "image-webp",
+ "gif",
+ "jpeg-decoder",
"log",
"pico-args",
+ "png",
"rgb",
"svgtypes",
"tiny-skia",
"usvg",
- "zune-jpeg 0.4.21",
]
[[package]]
@@ -3112,6 +1150,12 @@ dependencies = [
"bytemuck",
]
+[[package]]
+name = "roxmltree"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f"
+
[[package]]
name = "roxmltree"
version = "0.20.0"
@@ -3130,15 +1174,6 @@ version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
-[[package]]
-name = "rustc_version"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
-dependencies = [
- "semver",
-]
-
[[package]]
name = "rustix"
version = "0.38.44"
@@ -3173,16 +1208,14 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "rustybuzz"
-version = "0.20.1"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702"
+checksum = "88117946aa1bfb53c2ae0643ceac6506337f44887f8c9fbfb43587b1cc52ba49"
dependencies = [
"bitflags 2.11.1",
"bytemuck",
- "core_maths",
- "log",
"smallvec",
- "ttf-parser",
+ "ttf-parser 0.20.0",
"unicode-bidi-mirroring",
"unicode-ccc",
"unicode-properties",
@@ -3190,12 +1223,20 @@ dependencies = [
]
[[package]]
-name = "same-file"
-version = "1.0.6"
+name = "rustybuzz"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c"
dependencies = [
- "winapi-util",
+ "bitflags 2.11.1",
+ "bytemuck",
+ "libm",
+ "smallvec",
+ "ttf-parser 0.21.1",
+ "unicode-bidi-mirroring",
+ "unicode-ccc",
+ "unicode-properties",
+ "unicode-script",
]
[[package]]
@@ -3210,31 +1251,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-[[package]]
-name = "sctk-adwaita"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec"
-dependencies = [
- "ab_glyph",
- "log",
- "memmap2",
- "smithay-client-toolkit 0.19.2",
- "tiny-skia",
-]
-
[[package]]
name = "self_cell"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89"
-[[package]]
-name = "semver"
-version = "1.0.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
-
[[package]]
name = "serde"
version = "1.0.228"
@@ -3278,17 +1300,6 @@ dependencies = [
"zmij",
]
-[[package]]
-name = "serde_repr"
-version = "0.1.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "shlex"
version = "1.3.0"
@@ -3311,31 +1322,6 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
-[[package]]
-name = "simd_cesu8"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
-dependencies = [
- "rustc_version",
- "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"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
-
[[package]]
name = "simplecss"
version = "0.2.2"
@@ -3353,22 +1339,12 @@ checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
[[package]]
name = "skrifa"
-version = "0.37.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841"
-dependencies = [
- "bytemuck",
- "read-fonts 0.35.0",
-]
-
-[[package]]
-name = "skrifa"
-version = "0.40.0"
+version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac"
+checksum = "8e1c44ad1f6c5bdd4eefed8326711b7dbda9ea45dfd36068c427d332aa382cbe"
dependencies = [
"bytemuck",
- "read-fonts 0.37.0",
+ "read-fonts",
]
[[package]]
@@ -3399,12 +1375,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016"
dependencies = [
"bitflags 2.11.1",
- "calloop 0.13.0",
- "calloop-wayland-source 0.3.0",
+ "bytemuck",
+ "calloop",
+ "calloop-wayland-source",
"cursor-icon",
"libc",
"log",
- "memmap2",
+ "memmap2 0.9.10",
+ "pkg-config",
"rustix 0.38.44",
"thiserror 1.0.69",
"wayland-backend",
@@ -3414,56 +1392,10 @@ dependencies = [
"wayland-protocols",
"wayland-protocols-wlr",
"wayland-scanner",
+ "xkbcommon",
"xkeysym",
]
-[[package]]
-name = "smithay-client-toolkit"
-version = "0.20.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0"
-dependencies = [
- "bitflags 2.11.1",
- "calloop 0.14.4",
- "calloop-wayland-source 0.4.1",
- "cursor-icon",
- "libc",
- "log",
- "memmap2",
- "rustix 1.1.4",
- "thiserror 2.0.18",
- "wayland-backend",
- "wayland-client",
- "wayland-csd-frame",
- "wayland-cursor",
- "wayland-protocols",
- "wayland-protocols-experimental",
- "wayland-protocols-misc",
- "wayland-protocols-wlr",
- "wayland-scanner",
- "xkeysym",
-]
-
-[[package]]
-name = "smithay-clipboard"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71704c03f739f7745053bde45fa203a46c58d25bc5c4efba1d9a60e9dba81226"
-dependencies = [
- "libc",
- "smithay-client-toolkit 0.20.0",
- "wayland-backend",
-]
-
-[[package]]
-name = "smol_str"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
-dependencies = [
- "serde",
-]
-
[[package]]
name = "socket2"
version = "0.6.3"
@@ -3474,37 +1406,6 @@ dependencies = [
"windows-sys 0.61.2",
]
-[[package]]
-name = "softbuffer"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3"
-dependencies = [
- "as-raw-xcb-connection",
- "bytemuck",
- "fastrand",
- "js-sys",
- "memmap2",
- "ndk",
- "objc2 0.6.4",
- "objc2-core-foundation",
- "objc2-core-graphics",
- "objc2-foundation 0.3.2",
- "objc2-quartz-core 0.3.2",
- "raw-window-handle",
- "redox_syscall 0.5.18",
- "rustix 1.1.4",
- "tiny-xlib",
- "tracing",
- "wasm-bindgen",
- "wayland-backend",
- "wayland-client",
- "wayland-sys",
- "web-sys",
- "windows-sys 0.61.2",
- "x11rb",
-]
-
[[package]]
name = "spirv"
version = "0.3.0+sdk-1.3.268.0"
@@ -3514,12 +1415,6 @@ dependencies = [
"bitflags 2.11.1",
]
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
-
[[package]]
name = "static_assertions"
version = "1.1.0"
@@ -3535,6 +1430,28 @@ dependencies = [
"float-cmp",
]
+[[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",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn",
+]
+
[[package]]
name = "svg_fmt"
version = "0.4.5"
@@ -3547,17 +1464,17 @@ version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc"
dependencies = [
- "kurbo 0.11.3",
+ "kurbo",
"siphasher",
]
[[package]]
name = "swash"
-version = "0.2.7"
+version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "842f3cd369c2ba38966204f983eaa5e54a8e84a7d7159ed36ade2b6c335aae64"
+checksum = "cbd59f3f359ddd2c95af4758c18270eddd9c730dde98598023cdabff472c2ca2"
dependencies = [
- "skrifa 0.40.0",
+ "skrifa",
"yazi",
"zeno",
]
@@ -3582,19 +1499,6 @@ dependencies = [
"libc",
]
-[[package]]
-name = "tempfile"
-version = "3.27.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
-dependencies = [
- "fastrand",
- "getrandom 0.4.2",
- "once_cell",
- "rustix 1.1.4",
- "windows-sys 0.61.2",
-]
-
[[package]]
name = "termcolor"
version = "1.4.1"
@@ -3644,20 +1548,6 @@ dependencies = [
"syn",
]
-[[package]]
-name = "tiff"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52"
-dependencies = [
- "fax",
- "flate2",
- "half",
- "quick-error",
- "weezl",
- "zune-jpeg 0.5.15",
-]
-
[[package]]
name = "tiny-skia"
version = "0.11.4"
@@ -3669,7 +1559,7 @@ dependencies = [
"bytemuck",
"cfg-if",
"log",
- "png 0.17.16",
+ "png",
"tiny-skia-path",
]
@@ -3684,19 +1574,6 @@ dependencies = [
"strict-num",
]
-[[package]]
-name = "tiny-xlib"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a90a0ca3ee6a69f2ad28fd11621a4c3f03b371f366be500b64df260c4ffbafb4"
-dependencies = [
- "as-raw-xcb-connection",
- "ctor",
- "libloading",
- "pkg-config",
- "tracing",
-]
-
[[package]]
name = "tinyvec"
version = "1.11.0"
@@ -3740,87 +1617,17 @@ dependencies = [
"syn",
]
-[[package]]
-name = "toml_datetime"
-version = "1.1.1+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.25.11+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b"
-dependencies = [
- "indexmap",
- "toml_datetime",
- "toml_parser",
- "winnow",
-]
-
-[[package]]
-name = "toml_parser"
-version = "1.1.2+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
-dependencies = [
- "winnow",
-]
-
-[[package]]
-name = "tracing"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
-dependencies = [
- "log",
- "pin-project-lite",
- "tracing-attributes",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-attributes"
-version = "0.1.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.36"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
-dependencies = [
- "once_cell",
-]
-
[[package]]
name = "ttf-parser"
-version = "0.25.1"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
-dependencies = [
- "core_maths",
-]
+checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
[[package]]
-name = "uds_windows"
-version = "1.2.1"
+name = "ttf-parser"
+version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
-dependencies = [
- "memoffset",
- "tempfile",
- "windows-sys 0.61.2",
-]
+checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"
[[package]]
name = "unicode-bidi"
@@ -3830,15 +1637,15 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
[[package]]
name = "unicode-bidi-mirroring"
-version = "0.4.0"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe"
+checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86"
[[package]]
name = "unicode-ccc"
-version = "0.4.0"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e"
+checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656"
[[package]]
name = "unicode-ident"
@@ -3878,9 +1685,9 @@ checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94"
[[package]]
name = "unicode-width"
-version = "0.2.2"
+version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "unicode-xid"
@@ -3890,20 +1697,20 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "usvg"
-version = "0.45.1"
+version = "0.41.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80be9b06fbae3b8b303400ab20778c80bbaf338f563afe567cf3c9eea17b47ef"
+checksum = "5c704361d822337cfc00387672c7b59eaa72a1f0744f62b2a68aa228a0c6927d"
dependencies = [
"base64",
"data-url",
"flate2",
"fontdb",
"imagesize",
- "kurbo 0.11.3",
+ "kurbo",
"log",
"pico-args",
- "roxmltree",
- "rustybuzz",
+ "roxmltree 0.19.0",
+ "rustybuzz 0.13.0",
"simplecss",
"siphasher",
"strict-num",
@@ -3915,68 +1722,18 @@ dependencies = [
"xmlwriter",
]
-[[package]]
-name = "uuid"
-version = "1.23.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
-dependencies = [
- "js-sys",
- "serde_core",
- "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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
-[[package]]
-name = "walkdir"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
-dependencies = [
- "same-file",
- "winapi-util",
-]
-
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
-[[package]]
-name = "wasip2"
-version = "1.0.3+wasi-0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6"
-dependencies = [
- "wit-bindgen 0.57.1",
-]
-
-[[package]]
-name = "wasip3"
-version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
-dependencies = [
- "wit-bindgen 0.51.0",
-]
-
[[package]]
name = "wasm-bindgen"
version = "0.2.121"
@@ -4032,54 +1789,6 @@ dependencies = [
"unicode-ident",
]
-[[package]]
-name = "wasm-encoder"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
-dependencies = [
- "leb128fmt",
- "wasmparser",
-]
-
-[[package]]
-name = "wasm-metadata"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
-dependencies = [
- "anyhow",
- "indexmap",
- "wasm-encoder",
- "wasmparser",
-]
-
-[[package]]
-name = "wasmparser"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
-dependencies = [
- "bitflags 2.11.1",
- "hashbrown 0.15.5",
- "indexmap",
- "semver",
-]
-
-[[package]]
-name = "wasmtimer"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c598d6b99ea013e35844697fc4670d08339d5cda15588f193c6beedd12f644b"
-dependencies = [
- "futures",
- "js-sys",
- "parking_lot",
- "pin-utils",
- "slab",
- "wasm-bindgen",
-]
-
[[package]]
name = "wayland-backend"
version = "0.3.15"
@@ -4140,45 +1849,6 @@ dependencies = [
"wayland-scanner",
]
-[[package]]
-name = "wayland-protocols-experimental"
-version = "20250721.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1"
-dependencies = [
- "bitflags 2.11.1",
- "wayland-backend",
- "wayland-client",
- "wayland-protocols",
- "wayland-scanner",
-]
-
-[[package]]
-name = "wayland-protocols-misc"
-version = "0.3.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8"
-dependencies = [
- "bitflags 2.11.1",
- "wayland-backend",
- "wayland-client",
- "wayland-protocols",
- "wayland-scanner",
-]
-
-[[package]]
-name = "wayland-protocols-plasma"
-version = "0.3.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91"
-dependencies = [
- "bitflags 2.11.1",
- "wayland-backend",
- "wayland-client",
- "wayland-protocols",
- "wayland-scanner",
-]
-
[[package]]
name = "wayland-protocols-wlr"
version = "0.3.12"
@@ -4211,7 +1881,6 @@ checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be"
dependencies = [
"dlib",
"log",
- "once_cell",
"pkg-config",
]
@@ -4225,16 +1894,6 @@ dependencies = [
"wasm-bindgen",
]
-[[package]]
-name = "web-time"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
[[package]]
name = "weezl"
version = "0.1.12"
@@ -4243,21 +1902,18 @@ checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
[[package]]
name = "wgpu"
-version = "27.0.1"
+version = "24.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77"
+checksum = "6b0b3436f0729f6cdf2e6e9201f3d39dc95813fad61d826c1ed07918b4539353"
dependencies = [
"arrayvec",
"bitflags 2.11.1",
- "cfg-if",
"cfg_aliases",
"document-features",
- "hashbrown 0.16.1",
"js-sys",
"log",
"naga",
"parking_lot",
- "portable-atomic",
"profiling",
"raw-window-handle",
"smallvec",
@@ -4272,68 +1928,34 @@ dependencies = [
[[package]]
name = "wgpu-core"
-version = "27.0.3"
+version = "24.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7"
+checksum = "7f0aa306497a238d169b9dc70659105b4a096859a34894544ca81719242e1499"
dependencies = [
"arrayvec",
- "bit-set",
"bit-vec",
"bitflags 2.11.1",
- "bytemuck",
"cfg_aliases",
"document-features",
- "hashbrown 0.16.1",
"indexmap",
"log",
"naga",
"once_cell",
"parking_lot",
- "portable-atomic",
"profiling",
"raw-window-handle",
"rustc-hash 1.1.0",
"smallvec",
"thiserror 2.0.18",
- "wgpu-core-deps-apple",
- "wgpu-core-deps-emscripten",
- "wgpu-core-deps-windows-linux-android",
"wgpu-hal",
"wgpu-types",
]
-[[package]]
-name = "wgpu-core-deps-apple"
-version = "27.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0772ae958e9be0c729561d5e3fd9a19679bcdfb945b8b1a1969d9bfe8056d233"
-dependencies = [
- "wgpu-hal",
-]
-
-[[package]]
-name = "wgpu-core-deps-emscripten"
-version = "27.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b06ac3444a95b0813ecfd81ddb2774b66220b264b3e2031152a4a29fda4da6b5"
-dependencies = [
- "wgpu-hal",
-]
-
-[[package]]
-name = "wgpu-core-deps-windows-linux-android"
-version = "27.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3"
-dependencies = [
- "wgpu-hal",
-]
-
[[package]]
name = "wgpu-hal"
-version = "27.0.4"
+version = "24.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce"
+checksum = "f112f464674ca69f3533248508ee30cb84c67cf06c25ff6800685f5e0294e259"
dependencies = [
"android_system_properties",
"arrayvec",
@@ -4342,15 +1964,13 @@ dependencies = [
"bitflags 2.11.1",
"block",
"bytemuck",
- "cfg-if",
"cfg_aliases",
- "core-graphics-types 0.2.0",
+ "core-graphics-types",
"glow",
"glutin_wgl_sys",
"gpu-alloc",
"gpu-allocator",
"gpu-descriptor",
- "hashbrown 0.16.1",
"js-sys",
"khronos-egl",
"libc",
@@ -4363,32 +1983,29 @@ dependencies = [
"once_cell",
"ordered-float",
"parking_lot",
- "portable-atomic",
- "portable-atomic-util",
"profiling",
"range-alloc",
"raw-window-handle",
"renderdoc-sys",
+ "rustc-hash 1.1.0",
"smallvec",
"thiserror 2.0.18",
"wasm-bindgen",
"web-sys",
"wgpu-types",
- "windows 0.58.0",
- "windows-core 0.58.0",
+ "windows",
+ "windows-core",
]
[[package]]
name = "wgpu-types"
-version = "27.0.1"
+version = "24.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb"
+checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c"
dependencies = [
"bitflags 2.11.1",
- "bytemuck",
"js-sys",
"log",
- "thiserror 2.0.18",
"web-sys",
]
@@ -4402,114 +2019,33 @@ dependencies = [
]
[[package]]
-name = "window_clipboard"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5654226305eaf2dde8853fb482861d28e5dcecbbd40cb88e8393d94bb80d733"
-dependencies = [
- "clipboard-win",
- "clipboard_macos",
- "clipboard_wayland",
- "clipboard_x11",
- "raw-window-handle",
- "thiserror 2.0.18",
-]
-
-[[package]]
-name = "windows"
-version = "0.58.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
-dependencies = [
- "windows-core 0.58.0",
- "windows-targets",
-]
-
-[[package]]
-name = "windows"
-version = "0.62.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
-dependencies = [
- "windows-collections",
- "windows-core 0.62.2",
- "windows-future",
- "windows-numerics",
-]
-
-[[package]]
-name = "windows-collections"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
-dependencies = [
- "windows-core 0.62.2",
-]
-
-[[package]]
-name = "windows-core"
-version = "0.58.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
-dependencies = [
- "windows-implement 0.58.0",
- "windows-interface 0.58.0",
- "windows-result 0.2.0",
- "windows-strings 0.1.0",
- "windows-targets",
-]
-
-[[package]]
-name = "windows-core"
-version = "0.62.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
-dependencies = [
- "windows-implement 0.60.2",
- "windows-interface 0.59.3",
- "windows-link",
- "windows-result 0.4.1",
- "windows-strings 0.5.1",
-]
-
-[[package]]
-name = "windows-future"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
-dependencies = [
- "windows-core 0.62.2",
- "windows-link",
- "windows-threading",
-]
-
-[[package]]
-name = "windows-implement"
+name = "windows"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
+checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "windows-core",
+ "windows-targets",
]
[[package]]
-name = "windows-implement"
-version = "0.60.2"
+name = "windows-core"
+version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
+checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "windows-implement",
+ "windows-interface",
+ "windows-result",
+ "windows-strings",
+ "windows-targets",
]
[[package]]
-name = "windows-interface"
+name = "windows-implement"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
+checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [
"proc-macro2",
"quote",
@@ -4518,9 +2054,9 @@ dependencies = [
[[package]]
name = "windows-interface"
-version = "0.59.3"
+version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
+checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [
"proc-macro2",
"quote",
@@ -4533,16 +2069,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
-[[package]]
-name = "windows-numerics"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
-dependencies = [
- "windows-core 0.62.2",
- "windows-link",
-]
-
[[package]]
name = "windows-result"
version = "0.2.0"
@@ -4552,40 +2078,13 @@ dependencies = [
"windows-targets",
]
-[[package]]
-name = "windows-result"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
-dependencies = [
- "windows-link",
-]
-
[[package]]
name = "windows-strings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
- "windows-result 0.2.0",
- "windows-targets",
-]
-
-[[package]]
-name = "windows-strings"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
-dependencies = [
- "windows-link",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
+ "windows-result",
"windows-targets",
]
@@ -4623,15 +2122,6 @@ dependencies = [
"windows_x86_64_msvc",
]
-[[package]]
-name = "windows-threading"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37"
-dependencies = [
- "windows-link",
-]
-
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
@@ -4680,193 +2170,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
-[[package]]
-name = "winit"
-version = "0.30.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d"
-dependencies = [
- "ahash",
- "android-activity",
- "atomic-waker",
- "bitflags 2.11.1",
- "block2 0.5.1",
- "bytemuck",
- "calloop 0.13.0",
- "cfg_aliases",
- "concurrent-queue",
- "core-foundation 0.9.4",
- "core-graphics",
- "cursor-icon",
- "dpi",
- "js-sys",
- "libc",
- "memmap2",
- "ndk",
- "objc2 0.5.2",
- "objc2-app-kit 0.2.2",
- "objc2-foundation 0.2.2",
- "objc2-ui-kit",
- "orbclient",
- "percent-encoding",
- "pin-project",
- "raw-window-handle",
- "redox_syscall 0.4.1",
- "rustix 0.38.44",
- "sctk-adwaita",
- "smithay-client-toolkit 0.19.2",
- "smol_str",
- "tracing",
- "unicode-segmentation",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "wayland-backend",
- "wayland-client",
- "wayland-protocols",
- "wayland-protocols-plasma",
- "web-sys",
- "web-time",
- "windows-sys 0.52.0",
- "x11-dl",
- "x11rb",
- "xkbcommon-dl",
-]
-
-[[package]]
-name = "winnow"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "wit-bindgen"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
-dependencies = [
- "wit-bindgen-rust-macro",
-]
-
-[[package]]
-name = "wit-bindgen"
-version = "0.57.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
-
-[[package]]
-name = "wit-bindgen-core"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
-dependencies = [
- "anyhow",
- "heck",
- "wit-parser",
-]
-
-[[package]]
-name = "wit-bindgen-rust"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
-dependencies = [
- "anyhow",
- "heck",
- "indexmap",
- "prettyplease",
- "syn",
- "wasm-metadata",
- "wit-bindgen-core",
- "wit-component",
-]
-
-[[package]]
-name = "wit-bindgen-rust-macro"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
-dependencies = [
- "anyhow",
- "prettyplease",
- "proc-macro2",
- "quote",
- "syn",
- "wit-bindgen-core",
- "wit-bindgen-rust",
-]
-
-[[package]]
-name = "wit-component"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
-dependencies = [
- "anyhow",
- "bitflags 2.11.1",
- "indexmap",
- "log",
- "serde",
- "serde_derive",
- "serde_json",
- "wasm-encoder",
- "wasm-metadata",
- "wasmparser",
- "wit-parser",
-]
-
-[[package]]
-name = "wit-parser"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
-dependencies = [
- "anyhow",
- "id-arena",
- "indexmap",
- "log",
- "semver",
- "serde",
- "serde_derive",
- "serde_json",
- "unicode-xid",
- "wasmparser",
-]
-
-[[package]]
-name = "x11-dl"
-version = "2.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f"
-dependencies = [
- "libc",
- "once_cell",
- "pkg-config",
-]
-
-[[package]]
-name = "x11rb"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414"
-dependencies = [
- "as-raw-xcb-connection",
- "gethostname",
- "libc",
- "libloading",
- "once_cell",
- "rustix 1.1.4",
- "x11rb-protocol",
-]
-
-[[package]]
-name = "x11rb-protocol"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
-
[[package]]
name = "xcursor"
version = "0.3.10"
@@ -4874,15 +2177,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b"
[[package]]
-name = "xkbcommon-dl"
-version = "0.4.2"
+name = "xkbcommon"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5"
+checksum = "13867d259930edc7091a6c41b4ce6eee464328c6ff9659b7e4c668ca20d4c91e"
dependencies = [
- "bitflags 2.11.1",
- "dlib",
- "log",
- "once_cell",
+ "libc",
+ "memmap2 0.8.0",
"xkeysym",
]
@@ -4891,6 +2192,9 @@ name = "xkeysym"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56"
+dependencies = [
+ "bytemuck",
+]
[[package]]
name = "xml-rs"
@@ -4904,186 +2208,20 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
-[[package]]
-name = "y4m"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448"
-
[[package]]
name = "yazi"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5"
-
-[[package]]
-name = "zbus"
-version = "5.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3bcbf15c8708d7fc1be0c993622e0a5cbd5e8b52bfa40afa4c3e0cd8d724ac1"
-dependencies = [
- "async-broadcast",
- "async-executor",
- "async-io",
- "async-lock",
- "async-process",
- "async-recursion",
- "async-task",
- "async-trait",
- "blocking",
- "enumflags2",
- "event-listener",
- "futures-core",
- "futures-lite",
- "hex",
- "libc",
- "ordered-stream",
- "rustix 1.1.4",
- "serde",
- "serde_repr",
- "tracing",
- "uds_windows",
- "uuid",
- "windows-sys 0.61.2",
- "winnow",
- "zbus_macros",
- "zbus_names",
- "zvariant",
-]
-
-[[package]]
-name = "zbus_macros"
-version = "5.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51fa5406ad9175a8c825a931f8cf347116b531b3634fcb0b627c290f1f2516ff"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
- "zbus_names",
- "zvariant",
- "zvariant_utils",
-]
-
-[[package]]
-name = "zbus_names"
-version = "4.3.2"
+version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d"
-dependencies = [
- "serde",
- "winnow",
- "zvariant",
-]
+checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1"
[[package]]
name = "zeno"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524"
-
-[[package]]
-name = "zerocopy"
-version = "0.8.48"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
-dependencies = [
- "zerocopy-derive",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.8.48"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
+checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697"
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
-
-[[package]]
-name = "zune-core"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
-
-[[package]]
-name = "zune-core"
-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.4.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713"
-dependencies = [
- "zune-core 0.4.12",
-]
-
-[[package]]
-name = "zune-jpeg"
-version = "0.5.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296"
-dependencies = [
- "zune-core 0.5.1",
-]
-
-[[package]]
-name = "zvariant"
-version = "5.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee"
-dependencies = [
- "endi",
- "enumflags2",
- "serde",
- "winnow",
- "zvariant_derive",
- "zvariant_utils",
-]
-
-[[package]]
-name = "zvariant_derive"
-version = "5.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
- "zvariant_utils",
-]
-
-[[package]]
-name = "zvariant_utils"
-version = "3.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d464f5733ffa07a3164d656f18533caace9d0638596721355d73256a410d691"
-dependencies = [
- "proc-macro2",
- "quote",
- "serde",
- "syn",
- "winnow",
-]
diff --git a/Cargo.toml b/Cargo.toml
index 7060099..1537135 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,5 +4,15 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-iced = { version = "0.14", features = ["svg", "image", "tokio"] }
+clear-ui = { path = "../clear-ui" }
+smithay-client-toolkit = "0.19.2"
+calloop = "0.13.0"
+calloop-wayland-source = "0.3.0"
+wayland-client = { version = "0.31", features = ["system"] }
+xkeysym = "0.2"
+raw-window-handle = "0.6"
+wgpu = "24"
+bytemuck = { version = "1", features = ["derive"] }
+pollster = "0.4"
+glyphon = "0.8"
tokio = { version = "1", features = ["full"] }
diff --git a/src/main.rs b/src/main.rs
index 518def8..efc986c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,326 +1,1173 @@
mod pages;
-use iced::widget::{column, container, row, text};
-use iced::{keyboard, Color, Element, Length, Task, Theme};
+use wayland_client::QueueHandle;
+use glyphon::{FontSystem, Buffer, Metrics, Attrs};
+use clear_ui::engine::{Application, EngineState, LogicalPosition, LogicalSize, WindowSettings};
+use clear_ui::widget::{
+ MouseButton, ElementState, MouseScrollDelta, KeyEvent, TextItem, Widget,
+ TextBox, Button, TextLabel, Key, NamedKey, ScrollingList, Dropdown, Slider
+};
-use pages::Page;
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum Page {
+ Browse,
+ Keybindings,
+}
-// ── State ───────────────────────────────────────────────────────────
+impl Page {
+ pub const ALL: [Page; 2] = [
+ Page::Browse,
+ Page::Keybindings,
+ ];
-struct AppState {
- current_page: Page,
- browse: pages::browse::BrowseState,
- preview: pages::preview::PreviewState,
- details: pages::details::DetailsState,
- keybindings: pages::keybindings::KeybindingsState,
+ pub fn label(self) -> &'static str {
+ match self {
+ Page::Browse => "Browse",
+ Page::Keybindings => "Keys",
+ }
+ }
+
+ pub fn icon(self) -> &'static str {
+ match self {
+ Page::Browse => "🔤",
+ Page::Keybindings => "⌨",
+ }
+ }
}
-// ── Messages ────────────────────────────────────────────────────────
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum BrowseNavigation {
+ Up,
+ Down,
+}
#[derive(Debug, Clone)]
-enum Message {
+enum AppMessage {
+ Exit,
SwitchPage(Page),
- Browse(pages::browse::BrowseMessage),
- Preview(pages::preview::PreviewMessage),
- Details(pages::details::DetailsMessage),
- Keybindings(pages::keybindings::KeybindingsMessage),
- KeyboardEvent(keyboard::Event),
+ SelectFamily(usize),
+ SelectStyle(usize),
+ FontSizeChanged,
+ SearchChanged,
+ OpenFolder,
+ RemoveFont,
+ RefreshFonts,
}
-// ── View ────────────────────────────────────────────────────────────
+struct TypefaceApp {
+ // Sidebar
+ btn_browse: Button,
+ btn_keys: Button,
+
+ // Browse panel
+ search_box: TextBox,
+ font_list: ScrollingList,
+ font_buttons: Vec<Button>,
+
+ // Preview panel
+ style_dropdown: Dropdown,
+ size_slider: Slider,
+ preview_box: TextBox,
+
+ // Details panel
+ btn_open_folder: Button,
+ btn_remove_font: Button,
+
+ // State
+ current_page: Page,
+ all_fonts: Vec<pages::FontEntry>,
+ families: Vec<String>,
+ filtered: Vec<String>,
+ selected_idx: Option<usize>,
+ selected_family: Option<String>,
+ selected_style: Option<String>,
+ selected_file: Option<String>,
+ family_styles: Vec<String>,
+ family_files: Vec<String>,
+ charset_count: usize,
+ charset_str: String,
+ is_user_font: bool,
+
+ // UI metrics
+ width: u32,
+ height: u32,
+ scale_factor: f64,
+ text_items: Vec<TextItem>,
+ font_system: FontSystem,
+ needs_rebuild: bool,
+ status_text: String,
+}
+
+fn make_text_buffer_with_font(
+ fs: &mut FontSystem,
+ text: &str,
+ size: f32,
+ font: Option<&str>,
+ style: Option<glyphon::Style>,
+ weight: Option<glyphon::Weight>,
+) -> Buffer {
+ let metrics = Metrics::new(size, size * 1.4);
+ let mut buf = Buffer::new(fs, metrics);
+ let mut attrs = Attrs::new();
+ if let Some(font_name) = font {
+ attrs = attrs.family(glyphon::Family::Name(font_name));
+ }
+ if let Some(s) = style {
+ attrs = attrs.style(s);
+ }
+ if let Some(w) = weight {
+ attrs = attrs.weight(w);
+ }
+ buf.set_text(fs, text, attrs, glyphon::Shaping::Advanced);
+ buf.shape_until_scroll(fs, true);
+ buf
+}
+
+impl TypefaceApp {
+ fn reload_fonts(&mut self) {
+ self.all_fonts = pages::fetch_fonts();
+ self.families = self.extract_families(&self.all_fonts);
+ let query = if self.search_box.editing { &self.search_box.edit_buffer } else { &self.search_box.text };
+ self.filtered = self.filter_families(&self.families, query);
+ self.font_buttons = self.filtered.iter().map(|f| Button::new_list_row(0.0, 0.0, 0.0, 0.0).with_label(f)).collect();
+
+ if let Some(sel) = self.selected_idx {
+ if sel >= self.filtered.len() {
+ self.selected_idx = None;
+ self.selected_family = None;
+ self.selected_style = None;
+ self.selected_file = None;
+ self.family_styles.clear();
+ self.family_files.clear();
+ self.style_dropdown.options.clear();
+ self.style_dropdown.selected = 0;
+ self.charset_count = 0;
+ self.charset_str = String::from("0");
+ self.is_user_font = false;
+ } else {
+ let family = self.filtered[sel].clone();
+ self.select_family(family);
+ }
+ }
+ self.status_text = format!("Loaded {} fonts", self.all_fonts.len());
+ self.needs_rebuild = true;
+ }
+
+ fn extract_families(&self, fonts: &[pages::FontEntry]) -> Vec<String> {
+ let mut seen = std::collections::BTreeSet::new();
+ for f in fonts {
+ seen.insert(f.family.clone());
+ }
+ seen.into_iter().collect()
+ }
-fn view(state: &AppState) -> Element<'_, Message> {
- let bg = Color::from_rgb8(0x1a, 0x2a, 0x1c);
- let sidebar_bg = Color::from_rgb8(0x16, 0x24, 0x18);
+ fn filter_families(&self, families: &[String], query: &str) -> Vec<String> {
+ if query.is_empty() {
+ return families.to_vec();
+ }
+ let q = query.to_lowercase();
+ families
+ .iter()
+ .filter(|f| f.to_lowercase().contains(&q))
+ .cloned()
+ .collect()
+ }
- let mut sidebar = column![text("Clear Typeface")
- .size(15)
- .color(Color::from_rgb8(0x5c, 0x90, 0x60))]
- .spacing(4)
- .padding([16, 10]);
+ fn select_family(&mut self, family: String) {
+ self.selected_family = Some(family.clone());
+
+ // Find styles and files
+ let entries: Vec<&pages::FontEntry> = self.all_fonts.iter().filter(|f| f.family == family).collect();
+
+ let mut styles = Vec::new();
+ let mut files = Vec::new();
+ for e in entries {
+ styles.push(e.style.clone());
+ files.push(e.file.clone());
+ }
+
+ self.family_styles = styles.clone();
+ self.family_files = files.clone();
+
+ // Pick default style: "Regular" if available, else first
+ let default_idx = styles.iter().position(|s| s == "Regular").unwrap_or(0);
+
+ self.style_dropdown.options = styles;
+ self.style_dropdown.selected = default_idx;
+
+ if !self.family_styles.is_empty() {
+ let style = self.family_styles[default_idx].clone();
+ let file = self.family_files[default_idx].clone();
+ self.selected_style = Some(style);
+ self.selected_file = Some(file.clone());
+
+ self.charset_count = pages::count_chars(&file);
+ self.charset_str = self.charset_count.to_string();
+ self.is_user_font = pages::is_user_font(&file);
+ } else {
+ self.selected_style = None;
+ self.selected_file = None;
+ self.charset_count = 0;
+ self.charset_str = String::from("0");
+ self.is_user_font = false;
+ }
- for page in Page::ALL {
- sidebar = sidebar.push(pages::sidebar_button(page, page == state.current_page));
+ // Highlight selected button
+ if let Some(sel) = self.selected_idx {
+ for (idx, btn) in self.font_buttons.iter_mut().enumerate() {
+ btn.selected = idx == sel;
+ }
+ }
+
+ self.needs_rebuild = true;
+ }
+
+ fn scroll_to_index(&mut self, index: usize) {
+ let item_height_full = 24.0 + 4.0; // item_height + item_gap
+ let top = index as f32 * item_height_full;
+ let bottom = top + 24.0;
+ let viewport_top = self.font_list.scroll_box.scroll_y;
+ let viewport_bottom = viewport_top + self.font_list.scroll_box.viewport_h;
+
+ if bottom > viewport_bottom {
+ let max_scroll = (self.font_list.scroll_box.content_h - self.font_list.scroll_box.viewport_h).max(0.0);
+ self.font_list.scroll_box.scroll_y = (bottom - self.font_list.scroll_box.viewport_h).clamp(0.0, max_scroll);
+ } else if top < viewport_top {
+ self.font_list.scroll_box.scroll_y = top;
+ }
}
- let sidebar_container = container(sidebar)
- .width(200)
- .height(Length::Fill)
- .style(move |_theme| container::Style {
- background: Some(sidebar_bg.into()),
- border: iced::Border {
- radius: 12.0.into(),
- ..iced::Border::default()
- },
- ..container::Style::default()
+ fn rebuild_text_items(&mut self) {
+ self.text_items.clear();
+ let mut labels = Vec::new();
+ let font_system = &mut self.font_system;
+
+ // 1. Sidebar Page Buttons
+ self.btn_browse.prepare_text(font_system);
+ labels.extend(self.btn_browse.text_labels());
+
+ self.btn_keys.prepare_text(font_system);
+ labels.extend(self.btn_keys.text_labels());
+
+ // Sidebar Logo / Title
+ labels.push(TextLabel {
+ text: "Clear Typeface".to_string(),
+ x: 16.0,
+ y: 16.0,
+ font_size: 15.0,
+ color: [0x5c, 0x90, 0x60],
});
- let content: Element<Message> = match state.current_page {
- Page::Browse => browse_preview_view(state),
- Page::Keybindings => pages::keybindings::view(&state.keybindings),
- };
-
- let content_container = container(content)
- .width(Length::Fill)
- .height(Length::Fill)
- .padding(20)
- .style(move |_theme| container::Style {
- background: Some(bg.into()),
- border: iced::Border {
- radius: 12.0.into(),
- ..iced::Border::default()
- },
- ..container::Style::default()
+ // 2. Page Content
+ match self.current_page {
+ Page::Browse => {
+ // Left Panel (Browse List)
+ self.search_box.prepare_text(font_system);
+ for label in self.search_box.text_labels() {
+ let metrics = Metrics::new(label.font_size, label.font_size * 1.4);
+ let mut buf = Buffer::new(font_system, metrics);
+ buf.set_text(font_system, &label.text, Attrs::new(), glyphon::Shaping::Advanced);
+ buf.shape_until_scroll(font_system, true);
+ self.text_items.push(TextItem {
+ buffer: buf,
+ x: label.x,
+ y: label.y,
+ color: glyphon::Color::rgb(label.color[0], label.color[1], label.color[2]),
+ });
+ }
+
+ labels.push(TextLabel {
+ text: format!("{} families", self.filtered.len()),
+ x: 220.0,
+ y: 84.0,
+ font_size: 11.0,
+ color: [0x88, 0x88, 0x99],
+ });
+
+ // Visible Font Buttons
+ for (idx, btn) in self.font_buttons.iter_mut().enumerate() {
+ if self.font_list.get_item_draw_y(idx, 0.0).is_some() {
+ btn.prepare_text(font_system);
+ labels.extend(btn.text_labels());
+ }
+ }
+
+ // Middle Panel (Preview)
+ if let Some(ref family) = self.selected_family {
+ labels.push(TextLabel {
+ text: family.clone(),
+ x: 502.0,
+ y: 70.0,
+ font_size: 14.0,
+ color: [0x8f, 0xd4, 0x8f],
+ });
+
+ labels.push(TextLabel {
+ text: "Style:".to_string(),
+ x: 502.0,
+ y: 112.0,
+ font_size: 12.0,
+ color: [0x88, 0x88, 0x99],
+ });
+
+ self.style_dropdown.prepare_text(font_system);
+ for label in self.style_dropdown.text_labels() {
+ let metrics = Metrics::new(label.font_size, label.font_size * 1.4);
+ let mut buf = Buffer::new(font_system, metrics);
+ buf.set_text(font_system, &label.text, Attrs::new(), glyphon::Shaping::Advanced);
+ buf.shape_until_scroll(font_system, true);
+ self.text_items.push(TextItem {
+ buffer: buf,
+ x: label.x,
+ y: label.y,
+ color: glyphon::Color::rgb(label.color[0], label.color[1], label.color[2]),
+ });
+ }
+
+ labels.push(TextLabel {
+ text: format!("Size: {:.0}pt", self.size_slider.get_scaled_value()),
+ x: 502.0,
+ y: 152.0,
+ font_size: 12.0,
+ color: [0x88, 0x88, 0x99],
+ });
+
+ self.size_slider.prepare_text(font_system);
+ for label in self.size_slider.text_labels() {
+ let metrics = Metrics::new(label.font_size, label.font_size * 1.4);
+ let mut buf = Buffer::new(font_system, metrics);
+ buf.set_text(font_system, &label.text, Attrs::new(), glyphon::Shaping::Advanced);
+ buf.shape_until_scroll(font_system, true);
+ self.text_items.push(TextItem {
+ buffer: buf,
+ x: label.x,
+ y: label.y,
+ color: glyphon::Color::rgb(label.color[0], label.color[1], label.color[2]),
+ });
+ }
+
+ self.preview_box.prepare_text(font_system);
+ for label in self.preview_box.text_labels() {
+ let metrics = Metrics::new(label.font_size, label.font_size * 1.4);
+ let mut buf = Buffer::new(font_system, metrics);
+ buf.set_text(font_system, &label.text, Attrs::new(), glyphon::Shaping::Advanced);
+ buf.shape_until_scroll(font_system, true);
+ self.text_items.push(TextItem {
+ buffer: buf,
+ x: label.x,
+ y: label.y,
+ color: glyphon::Color::rgb(label.color[0], label.color[1], label.color[2]),
+ });
+ }
+
+ // Render Custom Font Preview text into text_items!
+ let font_size = self.size_slider.get_scaled_value();
+ let font_family = self.selected_family.as_deref();
+
+ let mut style_val = None;
+ let mut weight_val = None;
+ if let Some(ref style) = self.selected_style {
+ let sl = style.to_lowercase();
+ if sl.contains("italic") || sl.contains("oblique") {
+ style_val = Some(glyphon::Style::Italic);
+ }
+ if sl.contains("bold") {
+ weight_val = Some(glyphon::Weight::BOLD);
+ } else if sl.contains("light") {
+ weight_val = Some(glyphon::Weight::LIGHT);
+ } else if sl.contains("medium") {
+ weight_val = Some(glyphon::Weight::MEDIUM);
+ }
+ }
+
+ let preview_text = if self.preview_box.editing { &self.preview_box.edit_buffer } else { &self.preview_box.text };
+ let preview_buf = make_text_buffer_with_font(
+ font_system,
+ preview_text,
+ font_size,
+ font_family,
+ style_val,
+ weight_val,
+ );
+ self.text_items.push(TextItem {
+ buffer: preview_text_buffer_clamped(preview_buf, font_system, 360.0),
+ x: 512.0,
+ y: 242.0,
+ color: glyphon::Color::rgb(0xd4, 0xd4, 0xd4),
+ });
+
+ // Alphabet preview
+ let alphabet_text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789\n!@#$%^&*()_+-=[]{}|;':\",./<>";
+ let alph_buf = make_text_buffer_with_font(
+ font_system,
+ alphabet_text,
+ (font_size * 0.55).clamp(8.0, 36.0),
+ font_family,
+ style_val,
+ weight_val,
+ );
+ self.text_items.push(TextItem {
+ buffer: preview_text_buffer_clamped(alph_buf, font_system, 360.0),
+ x: 512.0,
+ y: 432.0,
+ color: glyphon::Color::rgb(0x88, 0x88, 0x99),
+ });
+
+ } else {
+ labels.push(TextLabel {
+ text: "Select a font from Browse to preview it here".to_string(),
+ x: 512.0,
+ y: 242.0,
+ font_size: 14.0,
+ color: [0x88, 0x88, 0x99],
+ });
+ }
+
+ // Render Dropdown popover labels if open
+ if self.style_dropdown.open && self.selected_family.is_some() {
+ let mut pc = clear_ui::layout::PopoverCollector::new();
+ self.style_dropdown.render_popover(&mut pc);
+ for (content, size, tx, ty, color, _font) in pc.texts {
+ let color_u8 = [
+ (color[0] * 255.0).clamp(0.0, 255.0) as u8,
+ (color[1] * 255.0).clamp(0.0, 255.0) as u8,
+ (color[2] * 255.0).clamp(0.0, 255.0) as u8,
+ ];
+ labels.push(TextLabel {
+ text: content,
+ x: tx,
+ y: ty,
+ font_size: size,
+ color: color_u8,
+ });
+ }
+ }
+
+ // Right Panel (Details)
+ if self.selected_family.is_some() {
+ labels.push(TextLabel {
+ text: "Font Details".to_string(),
+ x: 914.0,
+ y: 70.0,
+ font_size: 18.0,
+ color: [0x5c, 0x90, 0x60],
+ });
+
+ let family_str = self.selected_family.clone().unwrap_or_default();
+ let style_str = self.selected_style.clone().unwrap_or_default();
+ let file_str = self.selected_file.clone().unwrap_or_default();
+ let file_display = if file_str.len() > 32 {
+ format!("...{}", &file_str[file_str.len() - 29..])
+ } else {
+ file_str.clone()
+ };
+
+ labels.push(TextLabel { text: format!("Family: {}", family_str), x: 914.0, y: 110.0, font_size: 12.0, color: [0xdd, 0xdd, 0xe2] });
+ labels.push(TextLabel { text: format!("Style: {}", style_str), x: 914.0, y: 135.0, font_size: 12.0, color: [0xdd, 0xdd, 0xe2] });
+ labels.push(TextLabel { text: format!("File: {}", file_display), x: 914.0, y: 160.0, font_size: 12.0, color: [0xdd, 0xdd, 0xe2] });
+ labels.push(TextLabel { text: format!("Glyphs: {}", self.charset_str), x: 914.0, y: 185.0, font_size: 12.0, color: [0xdd, 0xdd, 0xe2] });
+ labels.push(TextLabel { text: format!("Loc: {}", if self.is_user_font { "User" } else { "System" }), x: 914.0, y: 210.0, font_size: 12.0, color: [0xdd, 0xdd, 0xe2] });
+
+ self.btn_open_folder.prepare_text(font_system);
+ labels.extend(self.btn_open_folder.text_labels());
+
+ self.btn_remove_font.prepare_text(font_system);
+ labels.extend(self.btn_remove_font.text_labels());
+ } else {
+ labels.push(TextLabel {
+ text: "Select a font from Browse to see details".to_string(),
+ x: 914.0,
+ y: 70.0,
+ font_size: 13.0,
+ color: [0x88, 0x88, 0x99],
+ });
+ }
+ }
+ Page::Keybindings => {
+ labels.push(TextLabel {
+ text: "Keybindings".to_string(),
+ x: 220.0,
+ y: 70.0,
+ font_size: 18.0,
+ color: [0x5c, 0x90, 0x60],
+ });
+
+ let sections: [(&str, &[(&str, &str)]); 3] = [
+ ("🧭 Navigation", &[
+ ("Ctrl + F", "Search fonts"),
+ ("Up / Down", "Navigate font list"),
+ ("Enter", "Select font"),
+ ("Ctrl + 1-2", "Switch page"),
+ ]),
+ ("👁 Preview", &[
+ ("+ / -", "Increase / decrease font size"),
+ ("Ctrl + E", "Edit preview text"),
+ ]),
+ ("⚡ Actions", &[
+ ("Ctrl + O", "Open font folder"),
+ ("Delete", "Remove user font"),
+ ("Ctrl + R / F5", "Refresh font list"),
+ ]),
+ ];
+
+ let mut y_offset = 110.0;
+ for (sec_title, bindings) in §ions {
+ labels.push(TextLabel {
+ text: sec_title.to_string(),
+ x: 220.0,
+ y: y_offset,
+ font_size: 14.0,
+ color: [0xdd, 0xdd, 0xe2],
+ });
+ y_offset += 24.0;
+
+ for (keys, action) in *bindings {
+ labels.push(TextLabel {
+ text: keys.to_string(),
+ x: 230.0,
+ y: y_offset,
+ font_size: 12.0,
+ color: [0x5c, 0x90, 0x60],
+ });
+ labels.push(TextLabel {
+ text: action.to_string(),
+ x: 370.0,
+ y: y_offset,
+ font_size: 12.0,
+ color: [0x88, 0x88, 0x99],
+ });
+ y_offset += 20.0;
+ }
+ y_offset += 16.0;
+ }
+ }
+ }
+
+ // 3. Status Bar Label
+ labels.push(TextLabel {
+ text: self.status_text.clone(),
+ x: 12.0,
+ y: self.height as f32 - 20.0,
+ font_size: 11.0,
+ color: [0x83, 0x83, 0x8a],
});
- let inner = row![sidebar_container, content_container]
- .width(Length::Fill)
- .height(Length::Fill)
- .spacing(6);
-
- container(inner)
- .width(Length::Fill)
- .height(Length::Fill)
- .padding(6)
- .style(move |_theme| container::Style {
- background: Some(bg.into()),
- ..container::Style::default()
- })
- .into()
+ // Convert TextLabels to text_items
+ for label in labels {
+ let metrics = Metrics::new(label.font_size, label.font_size * 1.4);
+ let mut buf = Buffer::new(font_system, metrics);
+ buf.set_text(font_system, &label.text, Attrs::new(), glyphon::Shaping::Advanced);
+ buf.shape_until_scroll(font_system, true);
+ self.text_items.push(TextItem {
+ buffer: buf,
+ x: label.x,
+ y: label.y,
+ color: glyphon::Color::rgb(label.color[0], label.color[1], label.color[2]),
+ });
+ }
+ }
}
-fn browse_preview_view(state: &AppState) -> Element<'_, Message> {
- let panel_bg = Color::from_rgb8(0x16, 0x24, 0x18);
- let heading = Color::from_rgb8(0x8f, 0xd4, 0x8f);
-
- let browse_panel = container(
- column![
- text("Browse").size(13).color(heading),
- pages::browse::view(&state.browse),
- ]
- .spacing(10)
- .width(Length::Fill)
- .height(Length::Fill),
- )
- .width(Length::FillPortion(2))
- .height(Length::Fill)
- .padding(14)
- .style(move |_theme| container::Style {
- background: Some(panel_bg.into()),
- border: iced::Border {
- radius: 10.0.into(),
- ..iced::Border::default()
- },
- ..container::Style::default()
- });
-
- let preview_panel = container(
- column![
- text("Preview").size(13).color(heading),
- pages::preview::view(&state.preview),
- ]
- .spacing(10)
- .width(Length::Fill)
- .height(Length::Fill),
- )
- .width(Length::FillPortion(3))
- .height(Length::Fill)
- .padding(14)
- .style(move |_theme| container::Style {
- background: Some(panel_bg.into()),
- border: iced::Border {
- radius: 10.0.into(),
- ..iced::Border::default()
- },
- ..container::Style::default()
- });
-
- let details_panel = container(
- column![
- text("Details").size(13).color(heading),
- pages::details::view(&state.details),
- ]
- .spacing(10)
- .width(Length::Fill)
- .height(Length::Fill),
- )
- .width(Length::FillPortion(2))
- .height(Length::Fill)
- .padding(14)
- .style(move |_theme| container::Style {
- background: Some(panel_bg.into()),
- border: iced::Border {
- radius: 10.0.into(),
- ..iced::Border::default()
- },
- ..container::Style::default()
- });
-
- row![browse_panel, preview_panel, details_panel]
- .spacing(12)
- .width(Length::Fill)
- .height(Length::Fill)
- .into()
+// Helpers to prevent preview text overflowing the panel width by wrapping or cropping
+fn preview_text_buffer_clamped(mut buf: Buffer, font_system: &mut FontSystem, max_width: f32) -> Buffer {
+ buf.set_size(font_system, Some(max_width), None);
+ buf.shape_until_scroll(font_system, true);
+ buf
}
-// ── Update ──────────────────────────────────────────────────────────
+impl Application for TypefaceApp {
+ type Message = AppMessage;
+
+ fn new(_qh: &QueueHandle<EngineState<Self>>, _sender: calloop::channel::Sender<Self::Message>) -> Self {
+ let btn_browse = Button::new(12.0, 50.0, 176.0, 32.0).with_label("🔤 Browse").with_selected(true);
+ let btn_keys = Button::new(12.0, 90.0, 176.0, 32.0).with_label("⌨ Keys");
+
+ let mut search_box = TextBox::new(String::new()).with_multiline(false).with_draw_bg_border(true);
+ search_box.font_size = 12.0;
+
+ let font_list = ScrollingList::new(24.0, 4.0);
-fn update(state: &mut AppState, message: Message) -> Task<Message> {
- match message {
- Message::SwitchPage(page) => {
- state.current_page = page;
- Task::none()
+ let style_dropdown = Dropdown::new(Vec::new(), 0);
+
+ let size_slider = Slider::new().with_range(8.0, 120.0).with_value((32.0 - 8.0) / (120.0 - 8.0)).with_readout(true);
+
+ let mut preview_box = TextBox::new(String::from("The quick brown fox jumps over the lazy dog")).with_multiline(false).with_draw_bg_border(true);
+ preview_box.font_size = 12.0;
+
+ let btn_open_folder = Button::new(914.0, 240.0, 110.0, 28.0).with_label("Open Folder");
+ let btn_remove_font = Button::new_reset(1034.0, 240.0, 110.0, 28.0).with_label("Remove Font");
+
+ let all_fonts = pages::fetch_fonts();
+ let mut app = Self {
+ btn_browse,
+ btn_keys,
+ search_box,
+ font_list,
+ font_buttons: Vec::new(),
+ style_dropdown,
+ size_slider,
+ preview_box,
+ btn_open_folder,
+ btn_remove_font,
+ current_page: Page::Browse,
+ all_fonts: all_fonts.clone(),
+ families: Vec::new(),
+ filtered: Vec::new(),
+ selected_idx: None,
+ selected_family: None,
+ selected_style: None,
+ selected_file: None,
+ family_styles: Vec::new(),
+ family_files: Vec::new(),
+ charset_count: 0,
+ charset_str: String::from("0"),
+ is_user_font: false,
+ width: 1200,
+ height: 720,
+ scale_factor: 1.0,
+ text_items: Vec::new(),
+ font_system: FontSystem::new(),
+ needs_rebuild: true,
+ status_text: format!("Loaded {} fonts", all_fonts.len()),
+ };
+
+ app.families = app.extract_families(&app.all_fonts);
+ app.filtered = app.filter_families(&app.families, "");
+ app.font_buttons = app.filtered.iter().map(|f| Button::new_list_row(0.0, 0.0, 0.0, 0.0).with_label(f)).collect();
+
+ // Auto-select first font at start if available
+ if !app.filtered.is_empty() {
+ app.selected_idx = Some(0);
+ let family = app.filtered[0].clone();
+ app.select_family(family);
}
- Message::Browse(msg) => {
- let family = match &msg {
- pages::browse::BrowseMessage::SelectFamily(idx) => {
- state.browse.filtered.get(*idx).cloned()
+
+ app
+ }
+
+ fn settings(&self) -> WindowSettings {
+ WindowSettings {
+ title: "Clear Typeface Interface".to_string(),
+ app_id: "clear-typeface-interface".to_string(),
+ width: 1200,
+ height: 720,
+ fullscreen: false,
+ min_size: Some((800, 500)),
+ }
+ }
+
+ fn update(&mut self, msg: Self::Message, needs_rebuild: &mut bool, exit: &mut bool) {
+ match msg {
+ AppMessage::Exit => {
+ *exit = true;
+ }
+ AppMessage::SwitchPage(page) => {
+ self.current_page = page;
+ self.btn_browse.selected = page == Page::Browse;
+ self.btn_keys.selected = page == Page::Keybindings;
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
+ }
+ AppMessage::SelectFamily(idx) => {
+ if idx < self.filtered.len() {
+ self.selected_idx = Some(idx);
+ let family = self.filtered[idx].clone();
+ self.select_family(family);
+ self.scroll_to_index(idx);
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
}
- _ => None,
- };
- let scroll_task = match &msg {
- pages::browse::BrowseMessage::SelectFamily(idx) => {
- Some(pages::browse::scroll_to_selection_if_needed(&state.browse, *idx))
+ }
+ AppMessage::SelectStyle(idx) => {
+ if idx < self.family_styles.len() {
+ self.style_dropdown.selected = idx;
+ let style = self.family_styles[idx].clone();
+ let file = self.family_files[idx].clone();
+ self.selected_style = Some(style);
+ self.selected_file = Some(file.clone());
+ self.charset_count = pages::count_chars(&file);
+ self.charset_str = self.charset_count.to_string();
+ self.is_user_font = pages::is_user_font(&file);
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
}
- _ => None,
- };
- let task = pages::browse::update(&mut state.browse, msg);
- // When a family is selected in browse, push it to preview
- if let Some(family) = family {
- let preview_task = pages::preview::update(
- &mut state.preview,
- pages::preview::PreviewMessage::SetFamily { family },
- &state.browse.all_fonts,
- );
-
- // Also update details with the preview's current style/file
- let details_task = pages::details::update(
- &mut state.details,
- pages::details::DetailsMessage::SetFont {
- family: state.preview.family.clone(),
- style: state.preview.style.clone(),
- file: state.preview.file.clone(),
- },
- );
-
- if let Some(scroll_task) = scroll_task {
- return Task::batch(vec![task, preview_task, details_task, scroll_task]);
+ }
+ AppMessage::FontSizeChanged => {
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
+ }
+ AppMessage::SearchChanged => {
+ let query = if self.search_box.editing { &self.search_box.edit_buffer } else { &self.search_box.text };
+ self.filtered = self.filter_families(&self.families, query);
+ self.font_buttons = self.filtered.iter().map(|f| Button::new_list_row(0.0, 0.0, 0.0, 0.0).with_label(f)).collect();
+
+ // reset or re-evaluate selection
+ self.selected_idx = None;
+ self.selected_family = None;
+ self.selected_style = None;
+ self.selected_file = None;
+ self.family_styles.clear();
+ self.family_files.clear();
+ self.style_dropdown.options.clear();
+ self.style_dropdown.selected = 0;
+ self.charset_count = 0;
+ self.charset_str = String::from("0");
+ self.is_user_font = false;
+
+ // Auto-select first match if available
+ if !self.filtered.is_empty() {
+ self.selected_idx = Some(0);
+ let family = self.filtered[0].clone();
+ self.select_family(family);
}
- return Task::batch(vec![task, preview_task, details_task]);
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
+ }
+ AppMessage::OpenFolder => {
+ if let Some(ref file) = self.selected_file {
+ if let Some(parent) = std::path::Path::new(file).parent() {
+ let _ = std::process::Command::new("xdg-open").arg(parent).spawn();
+ }
+ }
+ }
+ AppMessage::RemoveFont => {
+ if let Some(ref file) = self.selected_file {
+ if self.is_user_font {
+ let _ = std::process::Command::new("gio").args(["trash", file]).spawn();
+ let _ = std::process::Command::new("fc-cache").arg("-f").spawn();
+ self.reload_fonts();
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
+ }
+ }
+ }
+ AppMessage::RefreshFonts => {
+ self.reload_fonts();
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
}
- task
}
- Message::Preview(msg) => {
- // If a style was selected, also push it to details
- let details_msg = match &msg {
- pages::preview::PreviewMessage::StyleSelected(_) => {
- Some(pages::details::DetailsMessage::SetFont {
- family: state.preview.family.clone(),
- style: state.preview.style.clone(),
- file: state.preview.file.clone(),
- })
+ }
+
+ fn tick(&mut self, _dt: f32, _needs_rebuild: &mut bool) {}
+
+ fn view(&mut self, quads: &mut Vec<(f32, f32, f32, f32, [f32; 4])>, size: LogicalSize, scale: f64) {
+ let size_changed = self.width != size.width as u32 || self.height != size.height as u32 || self.scale_factor != scale;
+ if self.needs_rebuild || size_changed {
+ self.width = size.width as u32;
+ self.height = size.height as u32;
+ self.scale_factor = scale;
+
+ // Set coordinates of permanent widgets
+ self.btn_browse.set_rect(12.0, 50.0, 176.0, 32.0);
+ self.btn_keys.set_rect(12.0, 90.0, 176.0, 32.0);
+
+ if self.current_page == Page::Browse {
+ // Search box
+ self.search_box.set_rect(220.0, 50.0, 250.0, 26.0);
+
+ // Scrolling List
+ let list_x = 220.0;
+ let list_y = 100.0;
+ let list_w = 250.0;
+ let list_h = (self.height as f32 - 140.0).max(100.0);
+ self.font_list.set_rect(list_x, list_y, list_w, list_h);
+ self.font_list.update_bounds(self.filtered.len(), list_y, list_h);
+
+ // Layout list buttons
+ for (idx, btn) in self.font_buttons.iter_mut().enumerate() {
+ if let Some(draw_y) = self.font_list.get_item_draw_y(idx, 0.0) {
+ btn.set_rect(list_x + 4.0, draw_y, list_w - 8.0, 24.0);
+ } else {
+ btn.set_rect(-9999.0, -9999.0, 0.0, 0.0);
+ }
}
- _ => None,
- };
- let task = pages::preview::update(
- &mut state.preview,
- msg,
- &state.browse.all_fonts,
- );
- if details_msg.is_some() {
- // Re-read after update so style/file are current
- let details_msg = pages::details::DetailsMessage::SetFont {
- family: state.preview.family.clone(),
- style: state.preview.style.clone(),
- file: state.preview.file.clone(),
- };
- let details_task = pages::details::update(&mut state.details, details_msg);
- return Task::batch(vec![task, details_task]);
+
+ // Preview panel widgets
+ self.style_dropdown.set_rect(550.0, 100.0, 180.0, 26.0);
+ self.size_slider.set_rect(600.0, 140.0, 180.0, 20.0);
+ self.preview_box.set_rect(502.0, 180.0, 380.0, 30.0);
+
+ // Details panel buttons
+ self.btn_open_folder.set_rect(914.0, 240.0, 110.0, 28.0);
+ self.btn_remove_font.set_rect(1034.0, 240.0, 110.0, 28.0);
}
- task
+
+ self.rebuild_text_items();
+ self.needs_rebuild = false;
}
- Message::Details(msg) => pages::details::update(&mut state.details, msg),
- Message::Keybindings(msg) => pages::keybindings::update(&mut state.keybindings, msg),
- Message::KeyboardEvent(event) => {
- if state.current_page != Page::Browse {
- return Task::none();
+
+ let w_f32 = self.width as f32;
+ let h_f32 = self.height as f32;
+
+ // 1. General window background (dark green-tinted theme)
+ quads.push((0.0, 0.0, w_f32, h_f32, [0.102, 0.165, 0.110, 1.0]));
+
+ // 2. Sidebar background panel
+ quads.push((0.0, 40.0, 200.0, h_f32 - 70.0, [0.086, 0.141, 0.094, 1.0]));
+ quads.push((200.0, 40.0, 1.0, h_f32 - 70.0, [0.18, 0.28, 0.20, 1.0])); // sidebar separator
+
+ // 3. Header quads
+ quads.push((0.0, 0.0, w_f32, 40.0, [0.086, 0.141, 0.094, 1.0]));
+ quads.push((0.0, 40.0, w_f32, 1.0, [0.18, 0.28, 0.20, 1.0])); // header separator
+
+ // 4. Status Bar quads
+ let status_y = h_f32 - 30.0;
+ quads.push((0.0, status_y, w_f32, 30.0, [0.086, 0.141, 0.094, 1.0]));
+ quads.push((0.0, status_y, w_f32, 1.0, [0.18, 0.28, 0.20, 1.0])); // status separator
+
+ // Draw permanent buttons
+ quads.extend(self.btn_browse.extra_quads());
+ quads.extend(self.btn_keys.extra_quads());
+
+ // 5. Page Content
+ if self.current_page == Page::Browse {
+ // Draw panel separators / borders
+ // Left Panel (Browse list background)
+ quads.push((210.0, 50.0, 270.0, h_f32 - 90.0, [0.086, 0.141, 0.094, 1.0]));
+ quads.push((210.0, 50.0, 270.0, 1.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((210.0, 50.0 + h_f32 - 90.0, 270.0, 1.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((210.0, 50.0, 1.0, h_f32 - 90.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((480.0, 50.0, 1.0, h_f32 - 90.0, [0.18, 0.28, 0.20, 1.0]));
+
+ // Search box
+ quads.extend(self.search_box.extra_quads());
+
+ // Scrolling List
+ quads.extend(self.font_list.extra_quads());
+
+ // Font list items
+ for (idx, btn) in self.font_buttons.iter_mut().enumerate() {
+ if self.font_list.get_item_draw_y(idx, 0.0).is_some() {
+ quads.extend(btn.extra_quads());
+ }
}
- let direction = match event {
- keyboard::Event::KeyPressed {
- key: keyboard::Key::Named(keyboard::key::Named::ArrowUp),
- ..
- } => Some(pages::browse::BrowseNavigation::Up),
- keyboard::Event::KeyPressed {
- key: keyboard::Key::Named(keyboard::key::Named::ArrowDown),
- ..
- } => Some(pages::browse::BrowseNavigation::Down),
- _ => None,
- };
+ // Middle Panel (Preview)
+ quads.push((492.0, 50.0, 400.0, h_f32 - 90.0, [0.086, 0.141, 0.094, 1.0]));
+ quads.push((492.0, 50.0, 400.0, 1.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((492.0, 50.0 + h_f32 - 90.0, 400.0, 1.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((492.0, 50.0, 1.0, h_f32 - 90.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((892.0, 50.0, 1.0, h_f32 - 90.0, [0.18, 0.28, 0.20, 1.0]));
- if let Some(direction) = direction {
- if let Some(index) = pages::browse::next_selection_index(&state.browse, direction) {
- return update(state, Message::Browse(pages::browse::BrowseMessage::SelectFamily(index)));
+ if self.selected_family.is_some() {
+ // Dropdown
+ quads.extend(self.style_dropdown.extra_quads());
+ // Slider
+ quads.extend(self.size_slider.extra_quads());
+ // Custom text input
+ quads.extend(self.preview_box.extra_quads());
+
+ // Preview areas (frosted/darkened background inside panel)
+ quads.push((502.0, 230.0, 380.0, 180.0, [0.078, 0.133, 0.086, 1.0])); // preview box bg
+ quads.push((502.0, 230.0, 380.0, 1.0, [0.15, 0.25, 0.17, 1.0]));
+ quads.push((502.0, 410.0, 380.0, 1.0, [0.15, 0.25, 0.17, 1.0]));
+ quads.push((502.0, 230.0, 1.0, 180.0, [0.15, 0.25, 0.17, 1.0]));
+ quads.push((882.0, 230.0, 1.0, 180.0, [0.15, 0.25, 0.17, 1.0]));
+
+ quads.push((502.0, 420.0, 380.0, 120.0, [0.078, 0.133, 0.086, 1.0])); // alphabet box bg
+ quads.push((502.0, 420.0, 380.0, 1.0, [0.15, 0.25, 0.17, 1.0]));
+ quads.push((502.0, 540.0, 380.0, 1.0, [0.15, 0.25, 0.17, 1.0]));
+ quads.push((502.0, 420.0, 1.0, 120.0, [0.15, 0.25, 0.17, 1.0]));
+ quads.push((882.0, 420.0, 1.0, 120.0, [0.15, 0.25, 0.17, 1.0]));
+ }
+
+ // Right Panel (Details)
+ quads.push((904.0, 50.0, 286.0, h_f32 - 90.0, [0.086, 0.141, 0.094, 1.0]));
+ quads.push((904.0, 50.0, 286.0, 1.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((904.0, 50.0 + h_f32 - 90.0, 286.0, 1.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((904.0, 50.0, 1.0, h_f32 - 90.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((1190.0, 50.0, 1.0, h_f32 - 90.0, [0.18, 0.28, 0.20, 1.0]));
+
+ if self.selected_family.is_some() {
+ quads.extend(self.btn_open_folder.extra_quads());
+ quads.extend(self.btn_remove_font.extra_quads());
+ }
+ } else if self.current_page == Page::Keybindings {
+ // Keybindings page background
+ quads.push((210.0, 50.0, w_f32 - 220.0, h_f32 - 90.0, [0.086, 0.141, 0.094, 1.0]));
+ quads.push((210.0, 50.0, w_f32 - 220.0, 1.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((210.0, 50.0 + h_f32 - 90.0, w_f32 - 220.0, 1.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((210.0, 50.0, 1.0, h_f32 - 90.0, [0.18, 0.28, 0.20, 1.0]));
+ quads.push((w_f32 - 10.0, 50.0, 1.0, h_f32 - 90.0, [0.18, 0.28, 0.20, 1.0]));
+ }
+ }
+
+ fn overlay_quads(&mut self, quads: &mut Vec<(f32, f32, f32, f32, [f32; 4])>, _size: LogicalSize, _scale: f64) {
+ if self.current_page == Page::Browse && self.selected_family.is_some() {
+ // Style Dropdown popover rendered on top of everything
+ let mut pc = clear_ui::layout::PopoverCollector::new();
+ self.style_dropdown.render_popover(&mut pc);
+ quads.extend(pc.rects.iter().map(|&(c, x, y, w, h)| (x, y, w, h, c)));
+ }
+ }
+
+ fn text_items(&self) -> &[TextItem] {
+ &self.text_items
+ }
+
+ fn handle_pointer_move(&mut self, pos: LogicalPosition, needs_rebuild: &mut bool) {
+ let mut changed = false;
+ let px = pos.x as f32;
+ let py = pos.y as f32;
+
+ if self.btn_browse.on_cursor_moved(px, py) { changed = true; }
+ if self.btn_keys.on_cursor_moved(px, py) { changed = true; }
+
+ if self.current_page == Page::Browse {
+ if self.search_box.on_cursor_moved(px, py) { changed = true; }
+ if self.font_list.on_cursor_moved(px, py) { changed = true; }
+
+ // Font list items
+ for btn in &mut self.font_buttons {
+ if btn.rect().0 > -9000.0 {
+ if btn.on_cursor_moved(px, py) { changed = true; }
}
}
- Task::none()
+ if self.selected_family.is_some() {
+ if self.style_dropdown.on_cursor_moved(px, py) { changed = true; }
+ if self.size_slider.on_cursor_moved(px, py) { changed = true; }
+ if self.preview_box.on_cursor_moved(px, py) { changed = true; }
+ if self.btn_open_folder.on_cursor_moved(px, py) { changed = true; }
+ if self.btn_remove_font.on_cursor_moved(px, py) { changed = true; }
+ }
+ }
+
+ if changed {
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
}
}
-}
-// ── Subscription ────────────────────────────────────────────────────
+ fn handle_mouse_input(&mut self, button: MouseButton, state: ElementState, pos: LogicalPosition, needs_rebuild: &mut bool) -> Option<Self::Message> {
+ let mut changed = false;
+ let mut msg_out = None;
+ let px = pos.x as f32;
+ let py = pos.y as f32;
-fn subscription(state: &AppState) -> iced::Subscription<Message> {
- match state.current_page {
- Page::Browse => iced::Subscription::batch(vec![
- pages::browse::subscription(&state.browse),
- keyboard::listen().map(Message::KeyboardEvent),
- ]),
- Page::Keybindings => pages::keybindings::subscription(&state.keybindings),
+ // Permanent buttons
+ if self.btn_browse.mouse_input(button, state, px, py) {
+ changed = true;
+ if state == ElementState::Released && self.btn_browse.take_click() {
+ msg_out = Some(AppMessage::SwitchPage(Page::Browse));
+ }
+ }
+ if self.btn_keys.mouse_input(button, state, px, py) {
+ changed = true;
+ if state == ElementState::Released && self.btn_keys.take_click() {
+ msg_out = Some(AppMessage::SwitchPage(Page::Keybindings));
+ }
+ }
+
+ if self.current_page == Page::Browse {
+ // Dropdown has priority if open
+ let dropdown_was_open = self.style_dropdown.open;
+ if self.selected_family.is_some() && self.style_dropdown.mouse_input(button, state, px, py) {
+ changed = true;
+ if self.style_dropdown.take_change() {
+ msg_out = Some(AppMessage::SelectStyle(self.style_dropdown.selected));
+ }
+ }
+
+ if !dropdown_was_open {
+ if self.search_box.mouse_input(button, state, px, py) {
+ changed = true;
+ } else if state == ElementState::Pressed && button == MouseButton::Left {
+ self.search_box.unfocus();
+ changed = true;
+ }
+
+ if self.preview_box.mouse_input(button, state, px, py) {
+ changed = true;
+ } else if state == ElementState::Pressed && button == MouseButton::Left {
+ self.preview_box.unfocus();
+ changed = true;
+ }
+
+ if self.font_list.mouse_input(button, state, px, py) {
+ changed = true;
+ }
+
+ // Check list items
+ for (idx, btn) in self.font_buttons.iter_mut().enumerate() {
+ if btn.rect().0 > -9000.0 {
+ if btn.mouse_input(button, state, px, py) {
+ changed = true;
+ if state == ElementState::Released && btn.take_click() {
+ msg_out = Some(AppMessage::SelectFamily(idx));
+ }
+ }
+ }
+ }
+
+ if self.selected_family.is_some() {
+ if self.size_slider.mouse_input(button, state, px, py) {
+ changed = true;
+ msg_out = Some(AppMessage::FontSizeChanged);
+ }
+ if self.btn_open_folder.mouse_input(button, state, px, py) {
+ changed = true;
+ if state == ElementState::Released && self.btn_open_folder.take_click() {
+ msg_out = Some(AppMessage::OpenFolder);
+ }
+ }
+ if self.btn_remove_font.mouse_input(button, state, px, py) {
+ changed = true;
+ if state == ElementState::Released && self.btn_remove_font.take_click() {
+ msg_out = Some(AppMessage::RemoveFont);
+ }
+ }
+ }
+ }
+ }
+
+ if changed {
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
+ }
+
+ msg_out
}
-}
-// ── Boot / Theme / Title ────────────────────────────────────────────
+ fn handle_mouse_wheel(&mut self, delta: &MouseScrollDelta, pos: LogicalPosition, needs_rebuild: &mut bool) {
+ let mut changed = false;
+ let px = pos.x as f32;
+ let py = pos.y as f32;
-fn boot() -> (AppState, Task<Message>) {
- let state = AppState {
- current_page: Page::Browse,
- browse: pages::browse::BrowseState::default(),
- preview: pages::preview::PreviewState::new(),
- details: pages::details::DetailsState::default(),
- keybindings: pages::keybindings::KeybindingsState,
- };
+ if self.current_page == Page::Browse {
+ if self.font_list.mouse_wheel(delta, px, py) {
+ changed = true;
+ }
+ }
- // Load fonts on startup
- let task = Task::perform(
- async { pages::browse::fetch_fonts() },
- |f| Message::Browse(pages::browse::BrowseMessage::FontsLoaded(f)),
- );
+ if changed {
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
+ }
+ }
- (state, task)
-}
+ fn handle_key_input(&mut self, event: &KeyEvent, needs_rebuild: &mut bool) -> Option<Self::Message> {
+ let mut handled = false;
+ let mut msg_out = None;
-fn title(_state: &AppState) -> String {
- String::from("Clear Typeface Interface")
-}
+ // Custom keyboard shortcuts
+ if event.ctrl && event.state == ElementState::Pressed {
+ if let Key::Character(ref ch) = event.logical_key {
+ match ch.to_lowercase().as_str() {
+ "1" => {
+ msg_out = Some(AppMessage::SwitchPage(Page::Browse));
+ handled = true;
+ }
+ "2" => {
+ msg_out = Some(AppMessage::SwitchPage(Page::Keybindings));
+ handled = true;
+ }
+ "r" => {
+ msg_out = Some(AppMessage::RefreshFonts);
+ handled = true;
+ }
+ "f" => {
+ self.current_page = Page::Browse;
+ self.search_box.focus();
+ self.preview_box.unfocus();
+ handled = true;
+ }
+ "e" => {
+ self.current_page = Page::Browse;
+ self.preview_box.focus();
+ self.search_box.unfocus();
+ handled = true;
+ }
+ "o" => {
+ msg_out = Some(AppMessage::OpenFolder);
+ handled = true;
+ }
+ _ => {}
+ }
+ }
+ }
-fn theme(_state: &AppState) -> Theme {
- Theme::Dark
-}
+ if !handled && event.state == ElementState::Pressed {
+ match event.logical_key {
+ Key::Named(NamedKey::Delete) => {
+ msg_out = Some(AppMessage::RemoveFont);
+ handled = true;
+ }
+ Key::Character(ref ch) if ch == "+" || ch == "=" => {
+ if self.selected_family.is_some() {
+ let new_sz = (self.size_slider.get_scaled_value() + 2.0).min(120.0);
+ self.size_slider.set_value((new_sz - 8.0) / (120.0 - 8.0));
+ msg_out = Some(AppMessage::FontSizeChanged);
+ handled = true;
+ }
+ }
+ Key::Character(ref ch) if ch == "-" => {
+ if self.selected_family.is_some() {
+ let new_sz = (self.size_slider.get_scaled_value() - 2.0).max(8.0);
+ self.size_slider.set_value((new_sz - 8.0) / (120.0 - 8.0));
+ msg_out = Some(AppMessage::FontSizeChanged);
+ handled = true;
+ }
+ }
+ _ => {}
+ }
+ }
+
+ if !handled && self.current_page == Page::Browse {
+ // Arrow navigation
+ let direction = match event.logical_key {
+ Key::Named(NamedKey::ArrowUp) => Some(BrowseNavigation::Up),
+ Key::Named(NamedKey::ArrowDown) => Some(BrowseNavigation::Down),
+ _ => None,
+ };
-// ── Main ────────────────────────────────────────────────────────────
+ if let Some(dir) = direction {
+ if event.state == ElementState::Pressed && !self.filtered.is_empty() {
+ let len = self.filtered.len();
+ let next_idx = match (self.selected_idx, dir) {
+ (Some(idx), BrowseNavigation::Up) => idx.saturating_sub(1),
+ (Some(idx), BrowseNavigation::Down) => (idx + 1).min(len - 1),
+ (None, BrowseNavigation::Up) => len - 1,
+ (None, BrowseNavigation::Down) => 0,
+ };
+ msg_out = Some(AppMessage::SelectFamily(next_idx));
+ handled = true;
+ }
+ }
+ }
+
+ // TextBox inputs
+ if !handled && self.current_page == Page::Browse {
+ if self.search_box.focused() {
+ let old_text = if self.search_box.editing { self.search_box.edit_buffer.clone() } else { self.search_box.text.clone() };
+ if self.search_box.keyboard_input(event) {
+ handled = true;
+ let new_text = if self.search_box.editing { &self.search_box.edit_buffer } else { &self.search_box.text };
+ if old_text != *new_text {
+ msg_out = Some(AppMessage::SearchChanged);
+ }
+ }
+ } else if self.preview_box.focused() {
+ if self.preview_box.keyboard_input(event) {
+ handled = true;
+ }
+ }
+ }
+
+ if handled {
+ *needs_rebuild = true;
+ self.needs_rebuild = true;
+ }
-fn main() -> iced::Result {
- let mut window = iced::window::Settings::default();
- window.size = iced::Size::new(1200.0, 720.0);
- window.platform_specific.application_id = String::from("clear-typeface-interface");
+ msg_out
+ }
+}
- iced::application(boot, update, view)
- .title(title)
- .theme(theme)
- .subscription(subscription)
- .window(window)
- .run()
+fn main() {
+ let rt = tokio::runtime::Runtime::new().expect("tokio runtime");
+ let _guard = rt.enter();
+
+ clear_ui::engine::run::<TypefaceApp>();
}
diff --git a/src/pages.rs b/src/pages.rs
new file mode 100644
index 0000000..051c2fb
--- /dev/null
+++ b/src/pages.rs
@@ -0,0 +1,68 @@
+use std::process::Command;
+
+#[derive(Debug, Clone)]
+pub struct FontEntry {
+ pub family: String,
+ pub style: String,
+ pub file: String,
+}
+
+pub fn fetch_fonts() -> Vec<FontEntry> {
+ let output = match Command::new("fc-list")
+ .arg("--format=%{family}\\t%{style}\\t%{file}\\n")
+ .output()
+ {
+ Ok(o) => String::from_utf8_lossy(&o.stdout).into_owned(),
+ Err(_) => return Vec::new(),
+ };
+
+ let mut fonts: Vec<FontEntry> = output
+ .lines()
+ .filter_map(|line| {
+ let parts: Vec<&str> = line.splitn(3, '\t').collect();
+ if parts.len() == 3 {
+ Some(FontEntry {
+ family: parts[0].to_string(),
+ style: parts[1].to_string(),
+ file: parts[2].to_string(),
+ })
+ } else {
+ None
+ }
+ })
+ .collect();
+
+ fonts.sort_by(|a, b| a.family.to_lowercase().cmp(&b.family.to_lowercase()));
+ fonts.dedup_by(|a, b| a.family == b.family && a.style == b.style);
+ fonts
+}
+
+pub fn is_user_font(file: &str) -> bool {
+ file.starts_with("/home/") || file.contains(".local/share/fonts") || file.contains(".fonts")
+}
+
+pub fn count_chars(file: &str) -> usize {
+ let output = Command::new("fc-query")
+ .arg("--format=%{charset}")
+ .arg(file)
+ .output()
+ .ok();
+
+ match output {
+ Some(o) => {
+ let s = String::from_utf8_lossy(&o.stdout);
+ let mut count = 0usize;
+ for range in s.split_whitespace() {
+ if let Some((start, end)) = range.split_once('-') {
+ if let (Ok(s_val), Ok(e_val)) = (u32::from_str_radix(start, 16), u32::from_str_radix(end, 16)) {
+ count += (e_val - s_val + 1) as usize;
+ }
+ } else if let Ok(_) = u32::from_str_radix(range, 16) {
+ count += 1;
+ }
+ }
+ count
+ }
+ None => 0,
+ }
+}
diff --git a/src/pages/browse.rs b/src/pages/browse.rs
deleted file mode 100644
index 6ef6253..0000000
--- a/src/pages/browse.rs
+++ /dev/null
@@ -1,326 +0,0 @@
-use iced::widget::{button, column, operation, row, scrollable, text, text_input};
-use iced::{Color, Element, Length, Task};
-use iced::widget::scrollable::Viewport;
-use std::process::Command;
-
-use crate::Message;
-
-// ── Data ────────────────────────────────────────────────────────────
-
-#[derive(Debug, Clone)]
-pub struct FontEntry {
- pub family: String,
- pub style: String,
- pub file: String,
-}
-
-#[derive(Debug, Clone, Default)]
-pub struct BrowseState {
- /// All font entries from fc-list (one per family+style combo).
- pub all_fonts: Vec<FontEntry>,
- /// Deduplicated family names for the browse list.
- pub families: Vec<String>,
- /// Filtered subset of family names matching the search query.
- pub filtered: Vec<String>,
- pub search: String,
- /// Index into `filtered` — which family is highlighted.
- pub selected: Option<usize>,
- /// Tracks the scrollable viewport so we only scroll on
- /// keyboard navigation when the highlight is off-screen.
- pub scroll_offset_y: f32,
- pub viewport_height: f32,
-}
-
-#[derive(Debug, Clone)]
-pub enum BrowseMessage {
- SearchChanged(String),
- SelectFamily(usize),
- FontsLoaded(Vec<FontEntry>),
- Scrolled(Viewport),
- Tick,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum BrowseNavigation {
- Up,
- Down,
-}
-
-const LIST_SCROLL_ID: &str = "browse-font-list";
-const LIST_ROW_HEIGHT: f32 = 34.0;
-const LIST_ROW_SPACING: f32 = 2.0;
-
-// ── Helpers ─────────────────────────────────────────────────────────
-
-pub fn fetch_fonts() -> Vec<FontEntry> {
- let output = match Command::new("fc-list")
- .arg("--format=%{family}\\t%{style}\\t%{file}\\n")
- .output()
- {
- Ok(o) => String::from_utf8_lossy(&o.stdout).into_owned(),
- Err(_) => return Vec::new(),
- };
-
- let mut fonts: Vec<FontEntry> = output
- .lines()
- .filter_map(|line| {
- let parts: Vec<&str> = line.splitn(3, '\t').collect();
- if parts.len() == 3 {
- Some(FontEntry {
- family: parts[0].to_string(),
- style: parts[1].to_string(),
- file: parts[2].to_string(),
- })
- } else {
- None
- }
- })
- .collect();
-
- fonts.sort_by(|a, b| a.family.to_lowercase().cmp(&b.family.to_lowercase()));
- fonts.dedup_by(|a, b| a.family == b.family && a.style == b.style);
- fonts
-}
-
-/// Extract deduplicated family names, sorted alphabetically.
-fn extract_families(fonts: &[FontEntry]) -> Vec<String> {
- let mut seen = std::collections::BTreeSet::new();
- for f in fonts {
- seen.insert(f.family.clone());
- }
- seen.into_iter().collect()
-}
-
-fn filter_families(families: &[String], query: &str) -> Vec<String> {
- if query.is_empty() {
- return families.to_vec();
- }
- let q = query.to_lowercase();
- families
- .iter()
- .filter(|f| f.to_lowercase().contains(&q))
- .cloned()
- .collect()
-}
-
-/// Return all FontEntry items matching the given family name.
-pub fn entries_for_family<'a>(all_fonts: &'a [FontEntry], family: &str) -> Vec<&'a FontEntry> {
- all_fonts
- .iter()
- .filter(|f| f.family == family)
- .collect()
-}
-
-pub fn next_selection_index(state: &BrowseState, direction: BrowseNavigation) -> Option<usize> {
- let len = state.filtered.len();
-
- if len == 0 {
- return None;
- }
-
- match (state.selected, direction) {
- (Some(index), BrowseNavigation::Up) => Some(index.saturating_sub(1)),
- (Some(index), BrowseNavigation::Down) => Some((index + 1).min(len - 1)),
- (None, BrowseNavigation::Up) => Some(len - 1),
- (None, BrowseNavigation::Down) => Some(0),
- }
-}
-
-/// Row-top Y position for the given index.
-fn row_top(index: usize) -> f32 {
- index as f32 * (LIST_ROW_HEIGHT + LIST_ROW_SPACING)
-}
-
-/// Returns a scroll task only when the selected row is outside the
-/// visible viewport.
-pub fn scroll_to_selection_if_needed(
- state: &BrowseState,
- index: usize,
-) -> Task<Message> {
- let top = row_top(index);
- let bottom = top + LIST_ROW_HEIGHT;
- let viewport_top = state.scroll_offset_y;
- let viewport_bottom = viewport_top + state.viewport_height;
-
- if bottom <= viewport_top {
- operation::scroll_to(
- LIST_SCROLL_ID,
- scrollable::AbsoluteOffset { x: 0.0, y: top },
- )
- } else if top >= viewport_bottom {
- let new_offset = (bottom - state.viewport_height).max(0.0);
- operation::scroll_to(
- LIST_SCROLL_ID,
- scrollable::AbsoluteOffset { x: 0.0, y: new_offset },
- )
- } else {
- Task::none()
- }
-}
-
-// ── View ────────────────────────────────────────────────────────────
-
-pub fn view(state: &BrowseState) -> Element<'_, Message> {
- let text_fg = Color::from_rgb8(0xd4, 0xd4, 0xd4);
- let text_dim = Color::from_rgb8(0x88, 0x88, 0x99);
- let selected_bg = Color::from_rgb8(0x2a, 0x4a, 0x2e);
- let row_bg = Color::from_rgb8(0x1e, 0x2e, 0x20);
-
- let search_input = text_input("Search fonts...", &state.search)
- .on_input(|s| Message::Browse(BrowseMessage::SearchChanged(s)))
- .padding([8, 12]);
-
- let count_label = text(format!("{} families", state.filtered.len()))
- .size(11)
- .color(text_dim);
-
- let header = row![search_input, count_label]
- .spacing(8)
- .align_y(iced::Alignment::Center);
-
- let mut list = column![].spacing(2);
-
- for (i, family) in state.filtered.iter().enumerate() {
- let is_selected = state.selected == Some(i);
- let bg = if is_selected { selected_bg } else { row_bg };
- let fg = if is_selected {
- Color::from_rgb8(0x8f, 0xd4, 0x8f)
- } else {
- text_fg
- };
-
- let entry = button(
- text(family).size(13).color(fg),
- )
- .style(move |_theme, _status| button::Style {
- background: Some(bg.into()),
- border: iced::Border {
- radius: 4.0.into(),
- ..iced::Border::default()
- },
- ..button::Style::default()
- })
- .padding([6, 10])
- .height(LIST_ROW_HEIGHT)
- .width(Length::Fill)
- .on_press(Message::Browse(BrowseMessage::SelectFamily(i)));
-
- list = list.push(entry);
- }
-
- let scroll = scrollable(list)
- .id(LIST_SCROLL_ID)
- .height(Length::Fill)
- .on_scroll(|viewport| Message::Browse(BrowseMessage::Scrolled(viewport)));
-
- column![header, scroll,]
- .spacing(8)
- .width(Length::Fill)
- .height(Length::Fill)
- .into()
-}
-
-// ── Update ──────────────────────────────────────────────────────────
-
-pub fn update(state: &mut BrowseState, msg: BrowseMessage) -> Task<Message> {
- match msg {
- BrowseMessage::SearchChanged(q) => {
- state.search = q;
- state.filtered = filter_families(&state.families, &state.search);
- state.selected = None;
- Task::none()
- }
- BrowseMessage::SelectFamily(i) => {
- state.selected = Some(i);
- Task::none()
- }
- BrowseMessage::Scrolled(viewport) => {
- let offset = viewport.absolute_offset();
- state.scroll_offset_y = offset.y;
- state.viewport_height = viewport.bounds().height;
- Task::none()
- }
- BrowseMessage::FontsLoaded(fonts) => {
- let families = extract_families(&fonts);
- let filtered = filter_families(&families, &state.search);
- state.families = families;
- state.filtered = filtered;
- state.all_fonts = fonts;
- Task::none()
- }
- BrowseMessage::Tick => Task::perform(
- async { fetch_fonts() },
- |f| Message::Browse(BrowseMessage::FontsLoaded(f)),
- ),
- }
-}
-
-// ── Subscription ────────────────────────────────────────────────────
-
-pub fn subscription(_state: &BrowseState) -> iced::Subscription<Message> {
- iced::Subscription::none()
-}
-
-#[cfg(test)]
-mod tests {
- use super::{
- next_selection_index, row_top, BrowseNavigation, BrowseState,
- LIST_ROW_HEIGHT, LIST_ROW_SPACING, extract_families, filter_families,
- };
-
- fn state_with_count(count: usize) -> BrowseState {
- BrowseState {
- filtered: (0..count).map(|i| format!("Family {i}")).collect(),
- ..BrowseState::default()
- }
- }
-
- #[test]
- fn down_from_none_selects_first_entry() {
- let state = state_with_count(3);
- assert_eq!(next_selection_index(&state, BrowseNavigation::Down), Some(0));
- }
-
- #[test]
- fn up_from_none_selects_last_entry() {
- let state = state_with_count(3);
- assert_eq!(next_selection_index(&state, BrowseNavigation::Up), Some(2));
- }
-
- #[test]
- fn navigation_stays_in_bounds() {
- let mut state = state_with_count(3);
-
- state.selected = Some(0);
- assert_eq!(next_selection_index(&state, BrowseNavigation::Up), Some(0));
-
- state.selected = Some(2);
- assert_eq!(next_selection_index(&state, BrowseNavigation::Down), Some(2));
- }
-
- #[test]
- fn row_top_computes_y_position() {
- assert_eq!(row_top(0), 0.0);
- assert_eq!(row_top(1), LIST_ROW_HEIGHT + LIST_ROW_SPACING);
- assert_eq!(row_top(5), 5.0 * (LIST_ROW_HEIGHT + LIST_ROW_SPACING));
- }
-
- #[test]
- fn extract_families_deduplicates() {
- use super::{FontEntry, extract_families};
- let fonts = vec![
- FontEntry { family: "Arial".into(), style: "Regular".into(), file: "/a.ttf".into() },
- FontEntry { family: "Arial".into(), style: "Bold".into(), file: "/ab.ttf".into() },
- FontEntry { family: "Courier".into(), style: "Regular".into(), file: "/c.ttf".into() },
- ];
- let families = extract_families(&fonts);
- assert_eq!(families, vec!["Arial", "Courier"]);
- }
-
- #[test]
- fn filter_families_matches_substring() {
- let families = vec!["Arial".into(), "Courier".into(), "Arial Black".into()];
- let filtered = filter_families(&families, "arial");
- assert_eq!(filtered, vec!["Arial", "Arial Black"]);
- }
-}
diff --git a/src/pages/details.rs b/src/pages/details.rs
deleted file mode 100644
index 84851ba..0000000
--- a/src/pages/details.rs
+++ /dev/null
@@ -1,203 +0,0 @@
-use iced::widget::{button, column, row, text};
-use iced::{Color, Element, Length, Task};
-use std::process::Command;
-
-use crate::Message;
-
-fn detail_row<'a>(
- label: &'a str,
- value: &'a str,
- label_color: Color,
- value_color: Color,
-) -> iced::widget::Row<'a, Message, iced::Theme, iced::Renderer> {
- row![
- text(format!("{}:", label))
- .size(12)
- .color(label_color)
- .width(80),
- text(value).size(12).color(value_color),
- ]
- .spacing(4)
-}
-
-// ── Data ────────────────────────────────────────────────────────────
-
-#[derive(Debug, Clone, Default)]
-pub struct DetailsState {
- pub family: String,
- pub style: String,
- pub file: String,
- pub full_name: String,
- pub charset_count: usize,
- pub charset_str: String,
- pub is_user_font: bool,
-}
-
-#[derive(Debug, Clone)]
-pub enum DetailsMessage {
- SetFont {
- family: String,
- style: String,
- file: String,
- },
- RemoveFont,
- OpenFolder,
-}
-
-// ── Helpers ─────────────────────────────────────────────────────────
-
-fn is_user_font(file: &str) -> bool {
- file.starts_with("/home/") || file.contains(".local/share/fonts") || file.contains(".fonts")
-}
-
-fn count_chars(file: &str) -> usize {
- // Try to get character count from fc-query
- let output = Command::new("fc-query")
- .arg("--format=%{charset}")
- .arg(file)
- .output()
- .ok();
-
- match output {
- Some(o) => {
- let s = String::from_utf8_lossy(&o.stdout);
- // charset is a space-separated list of ranges like "0-127 160-255"
- let mut count = 0usize;
- for range in s.split_whitespace() {
- if let Some((start, end)) = range.split_once('-') {
- if let (Ok(s), Ok(e)) = (start.parse::<u32>(), end.parse::<u32>()) {
- count += (e - s + 1) as usize;
- }
- } else if let Ok(_v) = range.parse::<u32>() {
- count += 1;
- }
- }
- count
- }
- None => 0,
- }
-}
-
-// ── View ────────────────────────────────────────────────────────────
-
-pub fn view(state: &DetailsState) -> Element<'_, Message> {
- let accent = Color::from_rgb8(0x5c, 0x90, 0x60);
- let text_fg = Color::from_rgb8(0xd4, 0xd4, 0xd4);
- let text_dim = Color::from_rgb8(0x88, 0x88, 0x99);
- let danger = Color::from_rgb8(0xaa, 0x33, 0x33);
- let safe = Color::from_rgb8(0x33, 0x55, 0x38);
-
- if state.family.is_empty() {
- return column![text("Select a font from Browse to see details")
- .size(14)
- .color(text_dim),]
- .width(Length::Fill)
- .into();
- }
-
- let info_rows = column![
- detail_row("Family", &state.family, text_dim, text_fg),
- detail_row("Style", &state.style, text_dim, text_fg),
- detail_row("File", &state.file, text_dim, text_fg),
- detail_row("Characters", &state.charset_str, text_dim, text_fg),
- detail_row("Location", if state.is_user_font { "User" } else { "System" }, text_dim, text_fg),
- ]
- .spacing(6);
-
- let open_btn = button(text("Open Folder").color(Color::WHITE).size(12))
- .padding([8, 14])
- .style(move |_theme, _status| button::Style {
- background: Some(safe.into()),
- border: iced::Border {
- radius: 6.0.into(),
- ..iced::Border::default()
- },
- ..button::Style::default()
- })
- .on_press(Message::Details(DetailsMessage::OpenFolder));
-
- let remove_btn = if state.is_user_font {
- button(text("Remove Font").color(Color::WHITE).size(12))
- .padding([8, 14])
- .style(move |_theme, _status| button::Style {
- background: Some(danger.into()),
- border: iced::Border {
- radius: 6.0.into(),
- ..iced::Border::default()
- },
- ..button::Style::default()
- })
- .on_press(Message::Details(DetailsMessage::RemoveFont))
- } else {
- button(text("Remove Font").color(text_dim).size(12))
- .padding([8, 14])
- .style(move |_theme, _status| button::Style {
- background: Some(Color::from_rgb8(0x26, 0x26, 0x26).into()),
- border: iced::Border {
- radius: 6.0.into(),
- ..iced::Border::default()
- },
- ..button::Style::default()
- })
- };
-
- let actions = row![open_btn, remove_btn,].spacing(8);
-
- column![
- text("Font Details").size(18).color(accent),
- info_rows,
- actions,
- ]
- .spacing(12)
- .width(Length::Fill)
- .into()
-}
-
-// ── Update ──────────────────────────────────────────────────────────
-
-pub fn update(state: &mut DetailsState, msg: DetailsMessage) -> Task<Message> {
- match msg {
- DetailsMessage::SetFont { family, style, file } => {
- let charset_count = count_chars(&file);
- let is_user = is_user_font(&file);
- state.family = family;
- state.style = style;
- state.file = file;
- state.full_name = format!("{} {}", state.family, state.style);
- state.charset_count = charset_count;
- state.charset_str = charset_count.to_string();
- state.is_user_font = is_user;
- Task::none()
- }
- DetailsMessage::RemoveFont => {
- if !state.file.is_empty() && state.is_user_font {
- let file = state.file.clone();
- // Move to trash instead of rm for safety
- let _ = Command::new("gio")
- .args(["trash", &file])
- .spawn();
- let _ = Command::new("fc-cache")
- .arg("-f")
- .spawn();
- }
- Task::none()
- }
- DetailsMessage::OpenFolder => {
- if !state.file.is_empty() {
- let path = std::path::Path::new(&state.file);
- if let Some(parent) = path.parent() {
- let _ = Command::new("xdg-open")
- .arg(parent)
- .spawn();
- }
- }
- Task::none()
- }
- }
-}
-
-// ── Subscription ────────────────────────────────────────────────────
-
-pub fn subscription(_state: &DetailsState) -> iced::Subscription<Message> {
- iced::Subscription::none()
-}
diff --git a/src/pages/keybindings.rs b/src/pages/keybindings.rs
deleted file mode 100644
index c7228e3..0000000
--- a/src/pages/keybindings.rs
+++ /dev/null
@@ -1,105 +0,0 @@
-use iced::widget::{column, row, rule, text};
-use iced::{Color, Element, Length, Task};
-
-use crate::Message;
-
-// ── Data ────────────────────────────────────────────────────────────
-
-#[derive(Debug, Clone, Default)]
-pub struct KeybindingsState;
-
-#[derive(Debug, Clone)]
-pub enum KeybindingsMessage {}
-
-// ── Static data ────────────────────────────────────────────────────
-
-struct Binding {
- keys: &'static str,
- action: &'static str,
-}
-
-struct Section {
- title: &'static str,
- icon: &'static str,
- bindings: &'static [Binding],
-}
-
-const SECTIONS: &[Section] = &[
- Section {
- title: "Navigation",
- icon: "🧭",
- bindings: &[
- Binding { keys: "Ctrl + F", action: "Search fonts" },
- Binding { keys: "Up / Down", action: "Navigate font list" },
- Binding { keys: "Enter", action: "Select font" },
- Binding { keys: "Ctrl + 1-4", action: "Switch page" },
- ],
- },
- Section {
- title: "Preview",
- icon: "👁",
- bindings: &[
- Binding { keys: "+ / -", action: "Increase / decrease font size" },
- Binding { keys: "Ctrl + E", action: "Edit preview text" },
- ],
- },
- Section {
- title: "Actions",
- icon: "⚡",
- bindings: &[
- Binding { keys: "Ctrl + O", action: "Open font folder" },
- Binding { keys: "Delete", action: "Remove user font" },
- Binding { keys: "F5", action: "Refresh font list" },
- ],
- },
-];
-
-// ── View ────────────────────────────────────────────────────────────
-
-pub fn view(_state: &KeybindingsState) -> Element<'_, Message> {
- let accent = Color::from_rgb8(0x5c, 0x90, 0x60);
- let text_fg = Color::from_rgb8(0xd4, 0xd4, 0xd4);
- let text_dim = Color::from_rgb8(0x88, 0x88, 0x99);
-
- let mut content = column![text("Keybindings").size(18).color(accent)].spacing(12);
-
- for section in SECTIONS {
- let header = text(format!("{} {}", section.icon, section.title))
- .size(14)
- .color(text_fg);
-
- let mut rows = column![].spacing(4);
- for b in section.bindings {
- rows = rows.push(
- row![
- text(b.keys).size(12).color(accent).width(140),
- text(b.action).size(12).color(text_dim),
- ]
- .spacing(8),
- );
- }
-
- content = content.push(header);
- content = content.push(rows);
- content = content.push(rule::horizontal(1).style(|_theme| rule::Style {
- color: Color::from_rgb8(0x26, 0x33, 0x28),
- radius: 0.0.into(),
- fill_mode: rule::FillMode::Full,
- snap: true,
- }));
- }
-
- content.width(Length::Fill).into()
-}
-
-// ── Update ──────────────────────────────────────────────────────────
-
-pub fn update(_state: &mut KeybindingsState, _msg: KeybindingsMessage) -> Task<Message> {
- Task::none()
-}
-
-// ── Subscription ────────────────────────────────────────────────────
-
-pub fn subscription(_state: &KeybindingsState) -> iced::Subscription<Message> {
- iced::Subscription::none()
-}
diff --git a/src/pages/mod.rs b/src/pages/mod.rs
deleted file mode 100644
index 218996d..0000000
--- a/src/pages/mod.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-pub mod browse;
-pub mod preview;
-pub mod details;
-pub mod keybindings;
-
-use iced::widget::{button, text};
-use iced::{Color, Element, Length};
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum Page {
- Browse,
- Keybindings,
-}
-
-impl Page {
- pub const ALL: [Page; 2] = [
- Page::Browse,
- Page::Keybindings,
- ];
-
- pub fn label(self) -> &'static str {
- match self {
- Page::Browse => "Browse",
- Page::Keybindings => "Keys",
- }
- }
-
- pub fn icon(self) -> &'static str {
- match self {
- Page::Browse => "🔤",
- Page::Keybindings => "⌨",
- }
- }
-}
-
-pub fn sidebar_button(page: Page, active: bool) -> Element<'static, super::Message> {
- let bg = if active {
- Color::from_rgb8(0x2a, 0x4a, 0x2e)
- } else {
- Color::from_rgb8(0x1e, 0x2e, 0x20)
- };
-
- let fg = if active {
- Color::from_rgb8(0x8f, 0xd4, 0x8f)
- } else {
- Color::from_rgb8(0x99, 0x99, 0xaa)
- };
-
- button(
- iced::widget::row![]
- .spacing(8)
- .push(text(page.icon()).size(16))
- .push(text(page.label()).size(14).color(fg)),
- )
- .style(move |_theme, _status| button::Style {
- background: Some(bg.into()),
- border: iced::Border {
- radius: 6.0.into(),
- ..iced::Border::default()
- },
- ..button::Style::default()
- })
- .padding([10, 14])
- .width(Length::Fill)
- .on_press(super::Message::SwitchPage(page))
- .into()
-}
diff --git a/src/pages/preview.rs b/src/pages/preview.rs
deleted file mode 100644
index 872e314..0000000
--- a/src/pages/preview.rs
+++ /dev/null
@@ -1,216 +0,0 @@
-use iced::widget::{column, combo_box, container, row, slider, text, text_input};
-use iced::{Color, Element, Length, Task};
-
-use crate::Message;
-use crate::pages::browse::{FontEntry, entries_for_family};
-
-// ── Data ────────────────────────────────────────────────────────────
-
-#[derive(Debug, Clone, Default)]
-pub struct PreviewState {
- pub family: String,
- pub style: String,
- pub file: String,
- pub preview_text: String,
- pub font_size: f32,
- pub font: iced::Font,
- /// All FontEntry items for the currently selected family.
- pub family_entries: Vec<FontEntry>,
- /// Combo box state for the style dropdown.
- pub style_combo: combo_box::State<String>,
-}
-
-impl PreviewState {
- pub fn new() -> Self {
- Self {
- family: String::new(),
- style: String::new(),
- file: String::new(),
- preview_text: String::from("The quick brown fox jumps over the lazy dog"),
- font_size: 32.0,
- font: iced::Font::DEFAULT,
- family_entries: Vec::new(),
- style_combo: combo_box::State::new(Vec::new()),
- }
- }
-}
-
-#[derive(Debug, Clone)]
-pub enum PreviewMessage {
- SetFamily { family: String },
- StyleSelected(String),
- PreviewTextChanged(String),
- FontSizeChanged(f32),
-}
-
-// ── View ────────────────────────────────────────────────────────────
-
-pub fn view(state: &PreviewState) -> Element<'_, Message> {
- let accent = Color::from_rgb8(0x5c, 0x90, 0x60);
- let text_fg = Color::from_rgb8(0xd4, 0xd4, 0xd4);
- let text_dim = Color::from_rgb8(0x88, 0x88, 0x99);
-
- let font_label = if state.family.is_empty() {
- text("No font selected").size(14).color(text_dim)
- } else {
- text(&state.family).size(14).color(accent)
- };
-
- let style_label = text("Style:").size(12).color(text_dim);
-
- let selected_style = if state.style.is_empty() {
- None
- } else {
- Some(state.style.clone())
- };
-
- let style_dropdown = combo_box(
- &state.style_combo,
- "Select style...",
- selected_style.as_ref(),
- |style| Message::Preview(PreviewMessage::StyleSelected(style)),
- )
- .padding([6, 10]);
-
- let style_row = row![style_label, style_dropdown]
- .spacing(8)
- .align_y(iced::Alignment::Center);
-
- let size_label = text(format!("Size: {:.0}pt", state.font_size))
- .size(12)
- .color(text_dim);
-
- let size_slider = slider(8.0..=120.0, state.font_size, |v| {
- Message::Preview(PreviewMessage::FontSizeChanged(v))
- })
- .step(1.0);
-
- let text_input = text_input("Preview text...", &state.preview_text)
- .on_input(|s| Message::Preview(PreviewMessage::PreviewTextChanged(s)))
- .padding([8, 12]);
-
- let preview_font = state.font;
-
- let preview_text_widget = if state.family.is_empty() {
- text("Select a font from Browse to preview it here")
- .size(20)
- .color(text_dim)
- } else {
- text(state.preview_text.clone())
- .font(preview_font)
- .size(state.font_size)
- .color(text_fg)
- };
-
- let preview_area = container(preview_text_widget)
- .width(Length::Fill)
- .height(Length::Fill)
- .padding(20)
- .style(|_theme| container::Style {
- background: Some(Color::from_rgb8(0x14, 0x22, 0x16).into()),
- border: iced::Border {
- radius: 8.0.into(),
- ..iced::Border::default()
- },
- ..container::Style::default()
- });
-
- let alpha_text = text("ABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n0123456789\n!@#$%^&*()_+-=[]{}|;':\",./<>?")
- .font(state.font)
- .size(state.font_size * 0.6)
- .color(text_dim);
-
- let alpha_area = container(alpha_text)
- .width(Length::Fill)
- .padding(16)
- .style(|_theme| container::Style {
- background: Some(Color::from_rgb8(0x14, 0x22, 0x16).into()),
- border: iced::Border {
- radius: 8.0.into(),
- ..iced::Border::default()
- },
- ..container::Style::default()
- });
-
- column![
- font_label,
- style_row,
- row![size_label, size_slider,].spacing(8).align_y(iced::Alignment::Center),
- text_input,
- preview_area,
- alpha_area,
- ]
- .spacing(10)
- .width(Length::Fill)
- .height(Length::Fill)
- .into()
-}
-
-// ── Update ──────────────────────────────────────────────────────────
-
-pub fn update(state: &mut PreviewState, msg: PreviewMessage, all_fonts: &[FontEntry]) -> Task<Message> {
- match msg {
- PreviewMessage::SetFamily { family } => {
- state.family = family;
- state.family_entries = entries_for_family(all_fonts, &state.family)
- .into_iter()
- .cloned()
- .collect();
-
- let styles: Vec<String> = state.family_entries
- .iter()
- .map(|e| e.style.clone())
- .collect();
-
- // Pick the first style (or "Regular" if available)
- let default_style = styles
- .iter()
- .find(|s| *s == "Regular")
- .or(styles.first())
- .cloned()
- .unwrap_or_default();
-
- state.style_combo = combo_box::State::new(styles);
- state.style = default_style.clone();
-
- // Find the file for the default style
- state.file = state.family_entries
- .iter()
- .find(|e| e.style == default_style)
- .map(|e| e.file.clone())
- .unwrap_or_default();
-
- // Update the iced Font
- if state.family.is_empty() {
- state.font = iced::Font::DEFAULT;
- } else {
- let static_str: &'static str = state.family.clone().leak();
- state.font = iced::Font::with_name(static_str);
- }
- Task::none()
- }
- PreviewMessage::StyleSelected(style) => {
- state.style = style.clone();
- state.file = state.family_entries
- .iter()
- .find(|e| e.style == style)
- .map(|e| e.file.clone())
- .unwrap_or_default();
- Task::none()
- }
- PreviewMessage::PreviewTextChanged(s) => {
- state.preview_text = s;
- Task::none()
- }
- PreviewMessage::FontSizeChanged(v) => {
- state.font_size = v;
- Task::none()
- }
- }
-}
-
-// ── Subscription ────────────────────────────────────────────────────
-
-pub fn subscription(_state: &PreviewState) -> iced::Subscription<Message> {
- iced::Subscription::none()
-}