From 2dcc8a96d3d0e8a9be139882c5ec4653ab03e8f9 Mon Sep 17 00:00:00 2001 From: Kayshen-X Date: Tue, 5 May 2026 12:23:10 +0800 Subject: [PATCH] feat(workspace): pin Jian submodule and shell wrapper deps (Step 1a Task 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Anchor v19 pivot at the workspace level: vendor Jian as a git submodule pinned to fork commit ad13ce6 (P0.5 mini-gate GO; skia-safe 0.78 → 0.97 + new pub draw_on_canvas adapter), wire jian-core / jian-skia / jian-host-desktop as path deps with explicit version per spec §12.2, and re-export the Jian render/geometry/scene types from shell-core so shell-native can translate the OP RenderBackend facade into jian DrawOp commands. shell-core stays wasm32-clean: only jian-core (already wasm32-validated in P0.5) plus glam / bitflags / thiserror / tracing land here. shell-native picks up the full P0-pinned GL stack (skia-safe 0.97.0, glutin 0.32.3, glutin-winit 0.5.0, glow 0.17.0, winit 0.30.13, raw-window-handle 0.6.2, scopeguard 1.2) plus jian-skia (textlayout) and target-gated jian-host-desktop (default-features = false, no `run` feature so we skip Jian's softbuffer raster present path — OP owns its own GPU swap_buffers per spec §3.6). Adds OP RenderBackend trait + Rect / Color (with RED/GREEN/BLUE/BLACK/ WHITE/TRANSPARENT named constants per spec §5.2) + TextLayout facade that wraps jian_core::render::TextRun explicitly (TextRun has no Default impl, fields enumerated to honour spec §5.2 round-2 CONCERN-1 fix). Boundary checks all pass: - wasm32 shell-web metadata: no jian-host-desktop / jian-skia - aarch64-linux-android shell-native metadata: no jian-host-desktop - shell-core src: no glutin / skia_safe / winit / glow imports Tasks 2-4 (SharedSkiaContext + NativeBackend + ShellEvent mapping + acceptance) follow per plan v7. --- .gitmodules | 3 + Cargo.lock | 970 +++++++++++++----- Cargo.toml | 1 + crates/openpencil-shell-core/Cargo.toml | 17 +- crates/openpencil-shell-core/src/jian.rs | 41 + crates/openpencil-shell-core/src/lib.rs | 26 +- .../src/render_backend.rs | 181 ++++ .../tests/jian_re_export.rs | 87 ++ crates/openpencil-shell-native/Cargo.toml | 44 +- crates/openpencil-shell-native/src/lib.rs | 27 +- crates/openpencil-shell-web/src/lib.rs | 20 +- vendor/jian | 1 + 12 files changed, 1117 insertions(+), 301 deletions(-) create mode 100644 crates/openpencil-shell-core/src/jian.rs create mode 100644 crates/openpencil-shell-core/src/render_backend.rs create mode 100644 crates/openpencil-shell-core/tests/jian_re_export.rs create mode 160000 vendor/jian diff --git a/.gitmodules b/.gitmodules index 08e063365..e7d955d35 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "vendor/agent"] path = vendor/agent url = https://github.com/ZSeven-W/agent-rs.git +[submodule "vendor/jian"] + path = vendor/jian + url = git@github.com:Kayshen-X/jian.git diff --git a/Cargo.lock b/Cargo.lock index b063528da..138bafcd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,6 +18,12 @@ 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" @@ -32,10 +38,13 @@ dependencies = [ ] [[package]] -name = "allocator-api2" -version = "0.2.21" +name = "aho-corasick" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] [[package]] name = "android-activity" @@ -80,6 +89,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" +[[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" @@ -92,6 +112,32 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.11.1", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -110,7 +156,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2", + "objc2 0.5.2", ] [[package]] @@ -124,20 +170,12 @@ name = "bytemuck" version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" -dependencies = [ - "bytemuck_derive", -] [[package]] -name = "bytemuck_derive" -version = "1.10.2" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -183,6 +221,15 @@ dependencies = [ "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.4" @@ -195,6 +242,26 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "combine" version = "4.6.7" @@ -255,15 +322,12 @@ dependencies = [ ] [[package]] -name = "core-text" -version = "20.1.0" +name = "crc32fast" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ - "core-foundation", - "core-graphics", - "foreign-types", - "libc", + "cfg-if", ] [[package]] @@ -278,6 +342,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" +[[package]] +name = "deunicode" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04" + [[package]] name = "dispatch" version = "0.2.0" @@ -285,14 +355,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] -name = "displaydoc" -version = "0.2.5" +name = "dispatch2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "proc-macro2", - "quote", - "syn", + "bitflags 2.11.1", + "objc2 0.6.4", ] [[package]] @@ -316,6 +385,18 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "equivalent" version = "1.0.2" @@ -341,6 +422,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "filetime" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +dependencies = [ + "cfg-if", + "libc", + "libredox", +] + [[package]] name = "find-msvc-tools" version = "0.1.9" @@ -348,44 +440,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] -name = "font-types" -version = "0.7.3" +name = "flate2" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ - "bytemuck", -] - -[[package]] -name = "fontconfig-cache-parser" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f8afb20c8069fd676d27b214559a337cc619a605d25a87baa90b49a06f3b18" -dependencies = [ - "bytemuck", - "thiserror 1.0.69", -] - -[[package]] -name = "fontique" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b008f3607a8e8935b2607eef514164b8223020614c8ad684434a0cd668d280c" -dependencies = [ - "core-foundation", - "core-text", - "fontconfig-cache-parser", - "hashbrown 0.14.5", - "icu_locid", - "memmap2", - "objc2", - "objc2-foundation", - "peniko", - "roxmltree", - "skrifa", - "smallvec", - "windows", - "windows-core", + "crc32fast", + "miniz_oxide", ] [[package]] @@ -415,12 +476,71 @@ 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-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" @@ -433,8 +553,13 @@ 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", ] @@ -462,20 +587,126 @@ dependencies = [ ] [[package]] -name = "grid" -version = "0.15.0" +name = "gl_generator" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36119f3a540b086b4e436bb2b588cf98a68863470e0e880f4d0842f112a3183a" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glam" +version = "0.29.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "glow" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" +dependencies = [ + "bitflags 2.11.1", + "cfg_aliases", + "cgl", + "dispatch2", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "grid" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be136d9dacc2a13cc70bb6c8f902b414fb2641f8db1314637c6b7933411a8f82" + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" @@ -483,6 +714,22 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.5.2" @@ -490,15 +737,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] -name = "icu_locid" -version = "1.5.0" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", + "autocfg", + "hashbrown 0.12.3", + "serde", ] [[package]] @@ -511,12 +757,79 @@ dependencies = [ "hashbrown 0.17.0", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jian-core" +version = "0.0.1" +dependencies = [ + "async-trait", + "bitflags 2.11.1", + "deunicode", + "euclid", + "futures", + "jian-ops-schema", + "rstar", + "serde", + "serde_json", + "slotmap", + "smallvec", + "taffy", + "thiserror 1.0.69", +] + +[[package]] +name = "jian-host-desktop" +version = "0.0.1" +dependencies = [ + "async-trait", + "jian-core", + "jian-ops-schema", + "jian-skia", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "serde", + "serde_json", + "windows-sys 0.61.2", + "winit", +] + +[[package]] +name = "jian-ops-schema" +version = "0.0.1" +dependencies = [ + "schemars", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jian-skia" +version = "0.0.1" +dependencies = [ + "base64", + "futures", + "jian-core", + "jian-ops-schema", + "raw-window-handle", + "skia-safe", +] + [[package]] name = "jni" version = "0.22.4" @@ -598,15 +911,10 @@ dependencies = [ ] [[package]] -name = "kurbo" -version = "0.11.3" +name = "khronos_api" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62" -dependencies = [ - "arrayvec", - "euclid", - "smallvec", -] +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "libc" @@ -624,6 +932,12 @@ dependencies = [ "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" @@ -648,12 +962,6 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" -[[package]] -name = "litemap" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" - [[package]] name = "log" version = "0.4.29" @@ -675,6 +983,22 @@ dependencies = [ "libc", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[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 = "ndk" version = "0.9.0" @@ -705,6 +1029,16 @@ dependencies = [ "jni-sys 0.3.1", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -712,6 +1046,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -752,6 +1087,15 @@ dependencies = [ "objc2-encode", ] +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + [[package]] name = "objc2-app-kit" version = "0.2.2" @@ -761,13 +1105,25 @@ dependencies = [ "bitflags 2.11.1", "block2", "libc", - "objc2", + "objc2 0.5.2", "objc2-core-data", "objc2-core-image", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-quartz-core", ] +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.11.1", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-cloud-kit" version = "0.2.2" @@ -776,9 +1132,9 @@ checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.11.1", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -788,8 +1144,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -800,8 +1156,19 @@ checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.11.1", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.11.1", + "dispatch2", + "objc2 0.6.4", ] [[package]] @@ -811,8 +1178,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] @@ -823,9 +1190,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ "block2", - "objc2", + "objc2 0.5.2", "objc2-contacts", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -844,7 +1211,18 @@ dependencies = [ "block2", "dispatch", "libc", - "objc2", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.11.1", + "objc2 0.6.4", + "objc2-core-foundation", ] [[package]] @@ -854,9 +1232,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ "block2", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -867,8 +1245,8 @@ checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.11.1", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -879,8 +1257,8 @@ checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.11.1", "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", "objc2-metal", ] @@ -890,8 +1268,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" dependencies = [ - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -902,12 +1280,12 @@ checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.11.1", "block2", - "objc2", + "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", "objc2-core-image", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-link-presentation", "objc2-quartz-core", "objc2-symbols", @@ -922,8 +1300,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ "block2", - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -934,9 +1312,9 @@ checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.11.1", "block2", - "objc2", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -953,16 +1331,27 @@ version = "0.1.0" name = "openpencil-shell-core" version = "0.1.0" dependencies = [ - "parley", + "bitflags 2.11.1", + "glam", + "jian-core", "serde", - "taffy", + "thiserror 1.0.69", + "tracing", ] [[package]] name = "openpencil-shell-native" version = "0.1.0" dependencies = [ + "glow", + "glutin", + "glutin-winit", + "jian-host-desktop", + "jian-skia", "openpencil-shell-core", + "raw-window-handle", + "scopeguard", + "skia-safe", "winit", ] @@ -995,18 +1384,6 @@ dependencies = [ "ttf-parser", ] -[[package]] -name = "parley" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a67bad26b7aca3f1046305d0d7edba9a77b14e74a9ff9136968178c8e6c8e61" -dependencies = [ - "fontique", - "peniko", - "skrifa", - "swash", -] - [[package]] name = "pen-codegen" version = "0.1.0" @@ -1049,16 +1426,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "peniko" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a648c93f502a0bef0a9cb47fa1335994958a2744667d3f82defe513f276741a" -dependencies = [ - "kurbo", - "smallvec", -] - [[package]] name = "percent-encoding" version = "2.3.2" @@ -1117,6 +1484,16 @@ dependencies = [ "windows-sys 0.61.2", ] +[[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" @@ -1165,16 +1542,6 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" -[[package]] -name = "read-fonts" -version = "0.22.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f" -dependencies = [ - "bytemuck", - "font-types", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -1194,10 +1561,50 @@ dependencies = [ ] [[package]] -name = "roxmltree" -version = "0.19.0" +name = "regex" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "rstar" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421400d13ccfd26dfa5858199c30a5d76f9c54e0dba7575273025b43c5175dbb" +dependencies = [ + "heapless", + "num-traits", + "smallvec", +] + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc_version" @@ -1249,12 +1656,43 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + [[package]] name = "scoped-tls" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sctk-adwaita" version = "0.10.1" @@ -1304,12 +1742,24 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_json" version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ + "indexmap 2.14.0", "itoa", "memchr", "serde", @@ -1317,12 +1767,27 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + [[package]] name = "simd_cesu8" version = "1.1.1" @@ -1340,13 +1805,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] -name = "skrifa" -version = "0.22.3" +name = "skia-bindings" +version = "0.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1c44ad1f6c5bdd4eefed8326711b7dbda9ea45dfd36068c427d332aa382cbe" +checksum = "d6e3bcf8f25bf047e83110838463e8d06696c12fccc3d3794adf448b4d81f34b" dependencies = [ - "bytemuck", - "read-fonts", + "bindgen", + "cc", + "flate2", + "heck", + "pkg-config", + "regex", + "serde_json", + "tar", + "toml", +] + +[[package]] +name = "skia-safe" +version = "0.97.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "935d4d174fb749bac9265eb41cad75039d32fda2d9c1a1e81b430df0e210a409" +dependencies = [ + "bitflags 2.11.1", + "skia-bindings", ] [[package]] @@ -1404,21 +1886,18 @@ dependencies = [ "serde", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "strict-num" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" -[[package]] -name = "swash" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbd59f3f359ddd2c95af4758c18270eddd9c730dde98598023cdabff472c2ca2" -dependencies = [ - "skrifa", -] - [[package]] name = "syn" version = "2.0.117" @@ -1432,9 +1911,9 @@ dependencies = [ [[package]] name = "taffy" -version = "0.6.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136661daffcdfb128afb0d45a8f7e88078739196d64d7ffa47f8513f4a00a6d7" +checksum = "9cb893bff0f80ae17d3a57e030622a967b8dbc90e38284d9b4b1442e23873c94" dependencies = [ "arrayvec", "grid", @@ -1443,6 +1922,17 @@ dependencies = [ "slotmap", ] +[[package]] +name = "tar" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -1509,12 +1999,18 @@ dependencies = [ ] [[package]] -name = "tinystr" -version = "0.7.6" +name = "toml" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "displaydoc", + "indexmap 2.14.0", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] @@ -1532,7 +2028,7 @@ version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ - "indexmap", + "indexmap 2.14.0", "toml_datetime", "toml_parser", "winnow", @@ -1547,6 +2043,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tracing" version = "0.1.44" @@ -1554,14 +2056,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "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" @@ -1766,6 +2283,7 @@ checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" dependencies = [ "dlib", "log", + "once_cell", "pkg-config", ] @@ -1798,76 +2316,12 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core", - "windows-targets", -] - -[[package]] -name = "windows-core" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", - "windows-strings", - "windows-targets", -] - -[[package]] -name = "windows-implement" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -1982,9 +2436,9 @@ dependencies = [ "libc", "memmap2", "ndk", - "objc2", - "objc2-app-kit", - "objc2-foundation", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", "objc2-ui-kit", "orbclient", "percent-encoding", @@ -2026,12 +2480,6 @@ version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "writeable" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" - [[package]] name = "x11-dl" version = "2.21.0" @@ -2064,6 +2512,16 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix 1.1.4", +] + [[package]] name = "xcursor" version = "0.3.10" @@ -2089,6 +2547,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" +[[package]] +name = "xml-rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" + [[package]] name = "zerocopy" version = "0.8.48" diff --git a/Cargo.toml b/Cargo.toml index 10d4a0fda..657de2a59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ resolver = "2" members = ["crates/*"] exclude = [ "vendor/agent", + "vendor/jian", "node_modules", ] diff --git a/crates/openpencil-shell-core/Cargo.toml b/crates/openpencil-shell-core/Cargo.toml index 38b1df2d2..7a3b9e990 100644 --- a/crates/openpencil-shell-core/Cargo.toml +++ b/crates/openpencil-shell-core/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true rust-version.workspace = true license.workspace = true -description = "OpenPencil shell — retained-mode widget tree, RenderBackend trait, parley + taffy (kickoff spec §1.2)" +description = "OpenPencil shell — platform-agnostic widget facade + RenderBackend trait, Jian re-export wrapper (spec v19 §1.2 / §5.2)" [lib] name = "openpencil_shell_core" @@ -12,11 +12,18 @@ path = "src/lib.rs" [dependencies] serde = { workspace = true, optional = true } +thiserror = { workspace = true } +tracing = { workspace = true } -# Pinned per Task 0.4 wasm32 feature matrix verdict -# (notes/2026-05-02-parley-wasm-feature-matrix.md "## 结论" 段) -parley = { version = "0.2", default-features = false, features = ["std"] } -taffy = { version = "0.6", default-features = false, features = ["std", "taffy_tree", "flexbox", "grid", "block_layout", "content_size"] } +# v19 pivot: glam Vec2 用作 Point2D;bitflags 用于 widget facade 内部 flag。 +glam = { version = "0.29", default-features = false, features = ["std"] } +bitflags = "2" + +# v19 pivot: re-export Jian render/geometry/scene types (spec §5.2 widget-facing facade +# wraps jian-core; native-only deps live in shell-native, jian-core itself is wasm32-clean). +# 双写 path + version per spec §12.2 ("path dep with explicit version") —— 防 cargo +# 在不同 workspace context 下因 version 不一致退化到错版本。 +jian-core = { path = "../../vendor/jian/crates/jian-core", version = "0.0.1" } [features] default = [] diff --git a/crates/openpencil-shell-core/src/jian.rs b/crates/openpencil-shell-core/src/jian.rs new file mode 100644 index 000000000..2a7320d9c --- /dev/null +++ b/crates/openpencil-shell-core/src/jian.rs @@ -0,0 +1,41 @@ +//! Jian re-export module (spec v19 §2 / §1.2). +//! +//! `openpencil-shell-core` 是 Jian 薄 wrapper —— 把 +//! `jian_core::render::{DrawOp, Paint, TextRun, …}` 经 OP 层 re-export 给 +//! shell-native 内部翻译用。geometry / scene 类型加 `Jian*` 前缀,避免 +//! 与 OP 自有 `Rect` / `Color` (`render_backend.rs`) 冲突。 +//! +//! **契约(spec §5.2.1 §746 行)**:v19 wrapper 在 NativeBackend impl 内 +//! **不让 widget code 直接看到 `jian_core::render::DrawOp`** —— widget 只 +//! 调 OP `RenderBackend` method。这些 re-export 是给 **shell-native 内部** +//! 翻译用,不是给 widget code 用。 + +// ──────────────────────────────────────────────────────────────────────────── +// jian_core::render —— DrawOp 命令缓冲 + Paint / TextRun / 其它绘图描述符 +// ──────────────────────────────────────────────────────────────────────────── + +pub use jian_core::render::{ + BorderRadii, DrawOp, GradientStop, ImageSource, LinearGradient, Paint, PathCommand, + RadialGradient, RenderCommand, ShadowSpec, StrokeOp, TextAlign, TextRun, +}; + +// ──────────────────────────────────────────────────────────────────────────── +// jian_core::geometry —— 加 Jian* 前缀避免与 OP `Rect` 冲突 +// ──────────────────────────────────────────────────────────────────────────── + +/// Jian 的 axis-aligned 矩形 (`euclid::Rect`)。 +/// OP 自有 `crate::render_backend::Rect` 是 widget facade 用;shell-native +/// 内部翻译时把 OP `Rect` → `JianRect`(`origin/size` → `euclid::Rect::new`)。 +pub type JianRect = jian_core::geometry::Rect; +pub type Size = jian_core::geometry::Size; +pub type JianPoint = jian_core::geometry::Point; +pub type Affine2 = jian_core::geometry::Affine2; + +// ──────────────────────────────────────────────────────────────────────────── +// jian_core::scene —— Color (packed u32) 加 Jian* 前缀 +// ──────────────────────────────────────────────────────────────────────────── + +/// Jian 的 packed-RGBA 颜色 (`pub struct Color(pub u32)`);与 OP +/// `crate::render_backend::Color` (RGBA f32 quad) 不同。NativeBackend 内部 +/// 翻译 OP Color → JianColor 时用位打包。 +pub type JianColor = jian_core::scene::Color; diff --git a/crates/openpencil-shell-core/src/lib.rs b/crates/openpencil-shell-core/src/lib.rs index baeb1b45d..b7c7b5329 100644 --- a/crates/openpencil-shell-core/src/lib.rs +++ b/crates/openpencil-shell-core/src/lib.rs @@ -1,20 +1,18 @@ -//! OpenPencil shell core — platform-agnostic widget tree + render-backend trait. +//! OpenPencil shell core — platform-agnostic widget facade + RenderBackend trait. //! -//! Per kickoff spec §1.2 (FROZEN 2026-05-02): this crate must compile on +//! Per spec v19 §1.2 (FROZEN 2026-05-04): this crate must compile on //! wasm32-unknown-unknown. winit / accesskit_winit / skia-safe live in //! `openpencil-shell-native`; wasm-bindgen / web-sys / CanvasKit live in //! `openpencil-shell-web`. +//! +//! v19 pivot — 该 crate 是 Jian 薄 wrapper: +//! - [`jian`] 模块 re-export `jian_core::render::{DrawOp, Paint, TextRun, …}` +//! + geometry/scene aliases,给 shell-native 内部翻译用(widget code 看不到)。 +//! - [`render_backend`] 模块定义 OP 自有 widget-facing facade +//! (`RenderBackend` trait + `Rect` / `Color` / `TextLayout`,spec §5.2)。 -pub fn placeholder() -> &'static str { - "openpencil-shell-core skeleton" -} +pub mod jian; +pub mod render_backend; -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn skeleton_returns_string() { - assert_eq!(placeholder(), "openpencil-shell-core skeleton"); - } -} +// Re-export 主要 API 给上层 crate / widgets / tests 用。 +pub use render_backend::{Color, Point2D, Rect, RenderBackend, TextLayout}; diff --git a/crates/openpencil-shell-core/src/render_backend.rs b/crates/openpencil-shell-core/src/render_backend.rs new file mode 100644 index 000000000..b6738a56a --- /dev/null +++ b/crates/openpencil-shell-core/src/render_backend.rs @@ -0,0 +1,181 @@ +//! OP `RenderBackend` widget-facing facade (spec v19 §5.2). +//! +//! 这是 OP 的设计契约(method-style API:`fill_rect / stroke_rect / draw_text / +//! clip_rect / save / restore / translate / resize / dpi_scale`),与 Jian +//! `jian_core::render::RenderBackend`(command-buffer style,`new_surface / +//! begin_frame / draw(&DrawOp)` etc.)不直接重合。 +//! +//! 实现路径 (per §5.2.1): +//! - `NativeBackend` (shell-native, Step 1a 起 frame-scoped 设计):**不**直接 +//! impl 该 trait,而是 expose 同名 method 但带 `canvas: &skia_safe::Canvas` +//! 显式参数。Step 1a basic_window demo 通过 `SharedSkiaContext::with_frame` +//! 闭包内调 NativeBackend method。Step 1c+ 真接入 widget tree 时再考虑用 +//! `WithCanvas<'a>` newtype 把 canvas 注入 trait impl。 +//! - `WebCanvasKitBackend` (shell-web, Step 1b):内部用 CanvasKit JS binding。 +//! - `MobileBackend` (Step 1f):内部用 Metal / Vulkan / OpenGL ES。 +//! +//! 该模块**不**引 skia-safe / Canvas / GL 类型 —— shell-core 必须 wasm32-clean +//! (per spec §1.2 boundary)。 + +use jian_core::render::{TextAlign, TextRun}; + +/// 2D 坐标点(spec §5.2 钉死 `glam::Vec2`)。 +pub type Point2D = glam::Vec2; + +/// 矩形(origin + size 双 Vec2 表示)。 +#[derive(Debug, Clone, Copy)] +pub struct Rect { + pub origin: Point2D, + pub size: Point2D, +} + +/// RGBA color(widget facade 层;所有分量 0.0..=1.0)。 +/// +/// 命名常量定义在 OP 这层(spec v19 round 5 CONCERN-R5-3 fix); +/// `jian_core::scene::Color` 是 `Color(pub u32)` packed RGBA,没有 +/// RED/BLACK/etc 命名常量,调用方用 `JianColor::rgb(...)` 显式构造。 +#[derive(Debug, Clone, Copy)] +pub struct Color { + pub r: f32, + pub g: f32, + pub b: f32, + pub a: f32, +} + +impl Color { + pub const RED: Self = Self { + r: 1.0, + g: 0.0, + b: 0.0, + a: 1.0, + }; + pub const GREEN: Self = Self { + r: 0.0, + g: 1.0, + b: 0.0, + a: 1.0, + }; + pub const BLUE: Self = Self { + r: 0.0, + g: 0.0, + b: 1.0, + a: 1.0, + }; + pub const BLACK: Self = Self { + r: 0.0, + g: 0.0, + b: 0.0, + a: 1.0, + }; + pub const WHITE: Self = Self { + r: 1.0, + g: 1.0, + b: 1.0, + a: 1.0, + }; + pub const TRANSPARENT: Self = Self { + r: 0.0, + g: 0.0, + b: 0.0, + a: 0.0, + }; +} + +/// OP 的 TextLayout —— v19 删 parley 后定义在 OP 这层;薄薄包装 +/// `jian_core::render::TextRun`。 +/// +/// 不持 layout context / glyph cache(shell-core wasm32-clean,不能引 +/// skia/parley/icu);真 layout 在 NativeBackend::draw_text 时通过 +/// `jian_skia::SkiaBackend` 的 textlayout feature(skia textlayout, +/// ICU+harfbuzz)做 shape + line break。 +/// +/// Step 1a TextLayout 仅作 "已 shape 的 TextRun 集合" 占位; +/// caret/selection/bidi/wrap 推 Step 1c+。signatures 钉死,避免后续 Step +/// API break。 +#[derive(Debug, Clone)] +pub struct TextLayout { + runs: Vec, +} + +impl TextLayout { + /// 单 run 构造(Step 1a 唯一活跃路径;Phase B/C demo + raster_text_smoke 用)。 + /// + /// 字段对齐 `jian_core::render::TextRun` (`vendor/jian/crates/jian-core/src/render/paint.rs:77-94`): + /// **TextRun 没有 `Default` impl**,必须显式构造所有字段。 + /// - `content` / `font_family` / `font_size` / `color` / `origin`:调用方传入 + /// - `font_weight: 400` (CSS Normal) + /// - `max_width: 0.0`("unknown; render at origin with no alignment adjustment") + /// - `align: TextAlign::Start` + /// - `line_height: 0.0`("default") + pub fn single_run( + content: &str, + font_family: &str, + font_size: f32, + color: jian_core::scene::Color, + origin: Point2D, + ) -> Self { + let run = TextRun { + content: content.to_string(), + font_family: font_family.to_string(), + font_size, + font_weight: 400, + color, + origin: jian_core::geometry::Point::new(origin.x, origin.y), + max_width: 0.0, + align: TextAlign::Start, + line_height: 0.0, + }; + Self { runs: vec![run] } + } + + /// 已 shape 的 TextRun 集合视图。 + pub fn runs(&self) -> &[TextRun] { + &self.runs + } + + /// 平移所有 run 的 origin(NativeBackend::draw_text 在 widget origin + /// 基础上做平移)。返回新 layout,原 layout 不动。 + pub fn translated(&self, offset: Point2D) -> Self { + let runs = self + .runs + .iter() + .map(|r| { + let mut r2 = r.clone(); + r2.origin = + jian_core::geometry::Point::new(r.origin.x + offset.x, r.origin.y + offset.y); + r2 + }) + .collect(); + Self { runs } + } +} + +/// Backend 抽象(widget-facing facade,spec §5.2)。 +/// +/// 注:trait 不加 `Send` bound —— skia-safe 类型 `!Send`(rust-skia +/// thread-bound),Backend 在 render thread 内单独使用,无跨线程需求。 +/// +/// `NativeBackend` (shell-native) 在 1a **不**直接 impl 该 trait(v19 round 3 +/// BLOCK-R3-3 fix —— frame-scoped 设计避免跨帧 borrow),而是 expose 同名 +/// method 但带 `canvas: &skia_safe::Canvas` 显式参数。trait 签名内不出现任何 +/// Skia / GPU-backend 特定类型。 +pub trait RenderBackend { + /// Begin 帧,backend 内部维护 current frame state(不暴露 canvas 类型)。 + fn begin_frame(&mut self); + fn end_frame(&mut self); + + // 绘图 primitives —— widgets 调这些,不直接操作 canvas。 + fn fill_rect(&mut self, rect: Rect, color: Color); + fn stroke_rect(&mut self, rect: Rect, color: Color, width: f32); + fn draw_text(&mut self, layout: &TextLayout, origin: Point2D); + fn clip_rect(&mut self, rect: Rect); + + // 变换栈。 + fn save(&mut self); + fn restore(&mut self); + fn translate(&mut self, offset: Point2D); + + // viewport / dpi。 + fn resize(&mut self, width: u32, height: u32); + fn dpi_scale(&self) -> f32; +} diff --git a/crates/openpencil-shell-core/tests/jian_re_export.rs b/crates/openpencil-shell-core/tests/jian_re_export.rs new file mode 100644 index 000000000..5b22924c1 --- /dev/null +++ b/crates/openpencil-shell-core/tests/jian_re_export.rs @@ -0,0 +1,87 @@ +//! Task 1 Step 20-21: prove the Jian re-export wrapper compiles & is usable. +//! +//! Two anchor invariants for spec v19 §2 / §5.2: +//! 1. `DrawOp::Rect` constructible **through OP re-export path** +//! (`openpencil_shell_core::jian::DrawOp` —— shell-native 内部翻译用)。 +//! 2. `TextLayout::single_run` 产生**恰好一个** `TextRun`(spec §5.2, +//! 确认 `..Default::default()` 替代成显式字段后语义等价)。 + +use openpencil_shell_core::jian::{DrawOp, JianRect, Paint}; +use openpencil_shell_core::render_backend::{Color, Point2D, TextLayout}; + +#[test] +fn drawop_rect_constructible_via_re_export() { + // 通过 OP re-export 路径构造 Jian DrawOp::Rect —— 证明 shell-core 的 + // jian 模块把 jian_core::render::{DrawOp, Paint} 暴露出来了。 + let rect = JianRect::new( + jian_core::geometry::Point::new(0.0, 0.0), + jian_core::geometry::Size::new(100.0, 50.0), + ); + let paint = Paint::solid(jian_core::scene::Color::rgb(255, 0, 0)); + let op = DrawOp::Rect { rect, paint }; + + match op { + DrawOp::Rect { rect, .. } => { + assert_eq!(rect.size.width, 100.0); + assert_eq!(rect.size.height, 50.0); + } + _ => panic!("expected DrawOp::Rect"), + } +} + +#[test] +fn text_layout_single_run_creates_one_run() { + // 显式字段构造(TextRun 没 Default impl)—— 证明 spec §5.2 的 + // single_run 路径产生恰好一个 run,content/font_family/font_size + // 都按调用方传入设置。 + let layout = TextLayout::single_run( + "Hello", + "system-ui", + 16.0, + jian_core::scene::Color::rgb(0, 0, 0), + Point2D::new(10.0, 20.0), + ); + + assert_eq!(layout.runs().len(), 1); + + let run = &layout.runs()[0]; + assert_eq!(run.content, "Hello"); + assert_eq!(run.font_family, "system-ui"); + assert_eq!(run.font_size, 16.0); + assert_eq!(run.font_weight, 400); + assert_eq!(run.origin.x, 10.0); + assert_eq!(run.origin.y, 20.0); + assert_eq!(run.max_width, 0.0); + assert_eq!(run.line_height, 0.0); +} + +#[test] +fn text_layout_translated_offsets_origin() { + // translated() 把 offset 加到每 run origin 上;原 layout 不变。 + let layout = TextLayout::single_run( + "World", + "system-ui", + 14.0, + jian_core::scene::Color::rgb(0, 0, 0), + Point2D::new(5.0, 10.0), + ); + let shifted = layout.translated(Point2D::new(100.0, 200.0)); + + assert_eq!(shifted.runs()[0].origin.x, 105.0); + assert_eq!(shifted.runs()[0].origin.y, 210.0); + + // 原 layout 不动 + assert_eq!(layout.runs()[0].origin.x, 5.0); + assert_eq!(layout.runs()[0].origin.y, 10.0); +} + +#[test] +fn op_color_constants_distinct() { + // spec §5.2 命名常量 6 全 —— RED/GREEN/BLUE/BLACK/WHITE/TRANSPARENT。 + assert_eq!(Color::RED.r, 1.0); + assert_eq!(Color::GREEN.g, 1.0); + assert_eq!(Color::BLUE.b, 1.0); + assert_eq!(Color::BLACK.r, 0.0); + assert_eq!(Color::WHITE.r, 1.0); + assert_eq!(Color::TRANSPARENT.a, 0.0); +} diff --git a/crates/openpencil-shell-native/Cargo.toml b/crates/openpencil-shell-native/Cargo.toml index 4b012fb3c..b12416f48 100644 --- a/crates/openpencil-shell-native/Cargo.toml +++ b/crates/openpencil-shell-native/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true rust-version.workspace = true license.workspace = true -description = "OpenPencil shell — native (winit + skia-safe + accesskit) backend" +description = "OpenPencil shell — native (winit + skia-safe + accesskit) backend, integrating jian-skia + jian-host-desktop sub-pieces (spec v19 §3 / §5.2.1)" [lib] name = "openpencil_shell_native" @@ -17,17 +17,37 @@ openpencil-shell-core = { path = "../openpencil-shell-core", version = "0.1.0" } # 如果不 cfg-gate,cargo 会先 fetch + run skia-safe 的 build.rs(在 wasm32 上构建失败), # Step 5 grep `must NOT be compiled for wasm32` 永远命中不到——会被 skia 错误盖过。 # -# Phase 1 skeleton 阶段:故意保持 deps 最小,仅声明意图所需的核心 crate(winit)。 -# skia-safe / accesskit / accesskit_winit 等在 Stage F 真正实现 RenderBackend 时再加。 -# 原因:Rust 1.80 toolchain (rust-toolchain.toml) 对 home/hashbrown 等 crate 当前 -# 版本的 edition2024 / MSRV 1.81+ 需求不兼容,加完整依赖会导致下载阶段失败。 -# 详见提交说明 + Phase 1 Gate codex review。 +# v19 pivot (Task 1): 加 P0-pinned GL stack + jian-skia + jian-host-desktop。 +# - P0 dep-stack pin 来自 P0 probe(plan v7 §Task P0;skia-safe 0.97 + glow 0.17 + +# glutin 0.32.3 + glutin-winit 0.5.0 + winit 0.30.13 + raw-window-handle 0.6.2 + +# scopeguard 1.2 全在 macOS/Windows/Linux GO)。 +# - jian-skia (textlayout feature) 提供 SkiaBackend impl + skia textlayout(替代 parley)。 +# - jian-host-desktop (target-gate desktop only, 不含 `run` feature) 复用 PointerTranslator / +# scene::collect_draws_with_state / DesktopHost config helpers;OP 自管 GPU event loop, +# 不调 jian_host_desktop::run(softbuffer raster present 不需要)。 # # winit features 说明:on Linux 必须显式开 `x11` 和/或 `wayland`,否则 -# `platform_impl/mod.rs` 触发 `compile_error!("The platform you're compiling for is -# not supported by winit")`. macOS / Windows 各自的 backend 通过 cfg(target_os) -# 默认启用,不需要 feature flag。Step 1a 只在三大桌面 OS 跑 CI,所以同时打开 -# x11 + wayland 两个 Linux backend 就够。Stage F 真正接 RenderBackend 时会 -# 重新审视(可能加 `serde` / `rwh_06` 等)。 +# `platform_impl/mod.rs` 触发 `compile_error!`. macOS / Windows 各自的 backend 通过 +# cfg(target_os) 默认启用,不需要 feature flag。Step 1a 三大桌面 OS CI 都跑, +# 所以同时打开 x11 + wayland 两个 Linux backend 就够。 [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -winit = { version = "0.30", default-features = false, features = ["x11", "wayland", "wayland-csd-adwaita", "rwh_06"] } +skia-safe = { version = "0.97.0", features = ["gl"] } +glutin = "0.32.3" +glutin-winit = "0.5.0" +glow = "0.17.0" +winit = { version = "0.30.13", default-features = false, features = ["x11", "wayland", "wayland-csd-adwaita", "rwh_06"] } +raw-window-handle = "0.6.2" +scopeguard = "1.2" + +# Jian path deps —— 双写 path + version per spec §12.2。 +# jian-skia: 提供 SkiaBackend (RenderBackend impl) + skia textlayout (textlayout feature +# 需要 ICU + harfbuzz, ~15MB;P0.5 已升 skia-safe 0.78→0.97 + 新增 pub draw_on_canvas). +jian-skia = { path = "../../vendor/jian/crates/jian-skia", version = "0.0.1", features = ["textlayout"] } + +# jian-host-desktop: target-gate desktop only (Linux/macOS/Windows);不进 android/ios +# metadata(Task 1 Step 26 boundary check 验证)。 +# - default-features = false:Jian 默认 features 含 `run = ["dep:softbuffer"]` 拉 +# raster present;OP 自管 GPU event loop 不需要 softbuffer。 +# - features = ["textlayout"]:与 jian-skia 对齐文本路径。 +[target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies] +jian-host-desktop = { path = "../../vendor/jian/crates/jian-host-desktop", version = "0.0.1", default-features = false, features = ["textlayout"] } diff --git a/crates/openpencil-shell-native/src/lib.rs b/crates/openpencil-shell-native/src/lib.rs index 34447dc61..bc63d6f0d 100644 --- a/crates/openpencil-shell-native/src/lib.rs +++ b/crates/openpencil-shell-native/src/lib.rs @@ -1,20 +1,27 @@ //! OpenPencil shell — native (desktop) backend. //! -//! Per kickoff spec §1.2: this crate must NOT be linked into the wasm32-unknown-unknown -//! web bundle. Even though some deps (winit) compile silently on wasm32 via web-sys, -//! we use an explicit compile_error! guard to make accidental inclusion a hard error. +//! Per spec v19 §1.2 (FROZEN 2026-05-04): this crate must NOT be linked into +//! the wasm32-unknown-unknown web bundle. Even though some deps (winit) compile +//! silently on wasm32 via web-sys, we use an explicit compile_error! guard to +//! make accidental inclusion a hard error. +//! +//! Step 1a Task 1 状态:仅装 deps(P0-pinned GL stack + jian-skia + +//! jian-host-desktop);SharedSkiaContext / NativeBackend 实现在 Task 2 加。 #[cfg(target_arch = "wasm32")] compile_error!( "openpencil-shell-native must NOT be compiled for wasm32 targets. \ - Use openpencil-shell-web for browser builds (kickoff spec §1.2)." + Use openpencil-shell-web for browser builds (spec v19 §1.2)." ); -pub fn placeholder() -> String { - format!( - "openpencil-shell-native skeleton ({})", - openpencil_shell_core::placeholder() - ) +/// Skeleton placeholder until Task 2 lands `SharedSkiaContext` / `NativeBackend`. +/// +/// 用 OP `Color::RED` 命名常量证明 shell-core re-export 链通了;这是最小 +/// link-check (Step 1a Task 1 不实现 Skia surface 与 GL provider,那些 +/// 是 Task 2 的范围)。 +pub fn placeholder() -> &'static str { + let _red = openpencil_shell_core::Color::RED; + "openpencil-shell-native skeleton (Task 1: deps wired)" } #[cfg(test)] @@ -23,6 +30,6 @@ mod tests { #[test] fn skeleton_links_core() { - assert!(placeholder().contains("openpencil-shell-core")); + assert!(placeholder().contains("Task 1")); } } diff --git a/crates/openpencil-shell-web/src/lib.rs b/crates/openpencil-shell-web/src/lib.rs index a83e453b8..92b84211a 100644 --- a/crates/openpencil-shell-web/src/lib.rs +++ b/crates/openpencil-shell-web/src/lib.rs @@ -1,15 +1,21 @@ //! OpenPencil shell — web (wasm32) bundle entry. //! -//! Per kickoff spec §1.2: this crate is the web bundle entry. CI invariant -//! requires `cargo check --target wasm32-unknown-unknown -p openpencil-shell-web -//! --no-default-features --features web` to pass on every PR. +//! Per spec v19 §1.2 (FROZEN 2026-05-04): this crate is the web bundle entry. +//! CI invariant requires `cargo check --target wasm32-unknown-unknown -p +//! openpencil-shell-web --no-default-features --features web` to pass on +//! every PR. +//! +//! Step 1a Task 1 状态:仅 link-check shell-core re-export;CanvasKit +//! WebBackend 在 Step 1b 加。 use wasm_bindgen::prelude::*; +/// Skeleton placeholder until Step 1b lands `WebCanvasKitBackend`. +/// +/// 用 OP `Color::TRANSPARENT` 命名常量证明 shell-core re-export 在 wasm32 +/// 链通了;这是最小 link-check(shell-core 必须 wasm32-clean per spec §1.2)。 #[wasm_bindgen] pub fn placeholder() -> String { - format!( - "openpencil-shell-web skeleton ({})", - openpencil_shell_core::placeholder() - ) + let _t = openpencil_shell_core::Color::TRANSPARENT; + "openpencil-shell-web skeleton (Task 1: deps wired)".to_string() } diff --git a/vendor/jian b/vendor/jian new file mode 160000 index 000000000..ad13ce628 --- /dev/null +++ b/vendor/jian @@ -0,0 +1 @@ +Subproject commit ad13ce6283caf402e71608d362e837b09140331b