2026-03-22 14:56:27 +03:00
|
|
|
[package]
|
2026-05-23 17:16:15 +03:00
|
|
|
name = "OpenCADStudio"
|
2026-07-14 22:29:21 +03:00
|
|
|
version = "0.8.2"
|
2026-03-22 14:56:27 +03:00
|
|
|
edition = "2021"
|
|
|
|
|
build = "build.rs"
|
|
|
|
|
|
2026-06-15 01:36:04 +03:00
|
|
|
[workspace]
|
2026-07-11 01:27:17 +03:00
|
|
|
# `dwg-thumbnailer-win` is a Windows-only COM DLL (`#![cfg(windows)]`): it
|
|
|
|
|
# compiles to an empty cdylib on Linux/macOS and to the real handler on Windows,
|
|
|
|
|
# where the `build-windows` CI job (`cargo build --release`) compiles and thus
|
|
|
|
|
# verifies it.
|
|
|
|
|
members = [
|
|
|
|
|
"crates/ocs_plugin_api",
|
|
|
|
|
"crates/dwg-thumbnailer",
|
|
|
|
|
"crates/dwg-thumbnailer-win",
|
|
|
|
|
]
|
2026-06-15 01:36:04 +03:00
|
|
|
|
2026-06-16 04:10:01 +03:00
|
|
|
# Embed the application icon into the Windows .exe so Explorer, the taskbar,
|
|
|
|
|
# the Start-menu tile and file-association entries show it (issue #107).
|
|
|
|
|
[target.'cfg(windows)'.build-dependencies]
|
|
|
|
|
winresource = "0.1"
|
|
|
|
|
|
2026-06-16 13:01:19 +03:00
|
|
|
[features]
|
|
|
|
|
default = ["solid3d"]
|
|
|
|
|
# 3-D solid modelling: B-rep tessellation (truck-meshalgo) and booleans
|
|
|
|
|
# (truck-shapeops). Disabled for wasm builds — truck-meshalgo pulls
|
|
|
|
|
# vtkio → xz2 → lzma-sys (a C library) that does not cross-compile to
|
|
|
|
|
# wasm32. Without this feature the app is a 2-D CAD editor; the Model tab,
|
|
|
|
|
# solid tessellation and ACIS import become no-ops.
|
|
|
|
|
solid3d = ["dep:truck-meshalgo", "dep:truck-shapeops", "dep:lzma-sys"]
|
|
|
|
|
|
2026-03-22 14:56:27 +03:00
|
|
|
[dependencies]
|
refactor(config): consolidate settings into one grouped settings.json
App preferences were spread across six flat plain-text files (settings.txt,
recent.txt, recent_limit.txt, statusbar.txt, ribbon.txt, plot.txt), each with a
bespoke line parser and no grouping. Replace them with a single grouped JSON,
serialized via serde (enabling the derive feature; serde_json was already a
dependency).
- New app/config.rs: AppConfig { settings, recent, statusbar, ribbon, plot } →
<config>/settings.json (pretty JSON), load()/save().
- Make UserSettings, StatusBarConfig/StatusPill, CollapseMode and
PlotDialogState serde-derived; #[serde(skip)] marks the plot dialog's runtime
fields so only print preferences persist. Their bespoke .txt load/save is
removed.
- App gains current_config/apply_config/save_config: one AppConfig::load at
startup distributes into live state; every settings-change site
(persist_settings_if_changed, recent add/remove/limit, status-bar pill
toggle, ribbon density, plot commit) routes through save_config, which diffs
against the last write to avoid thrashing.
- Clean start: the old flat files are ignored (no migration). ocad.pgp stays a
separate hand-editable file.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 16:41:34 +03:00
|
|
|
# JSON: plugin marketplace / Patreon fetch (native) + web supporters.json parse,
|
|
|
|
|
# and the consolidated user config (settings.json) via serde-derived structs.
|
2026-07-02 01:25:24 +03:00
|
|
|
serde_json = "1"
|
refactor(config): consolidate settings into one grouped settings.json
App preferences were spread across six flat plain-text files (settings.txt,
recent.txt, recent_limit.txt, statusbar.txt, ribbon.txt, plot.txt), each with a
bespoke line parser and no grouping. Replace them with a single grouped JSON,
serialized via serde (enabling the derive feature; serde_json was already a
dependency).
- New app/config.rs: AppConfig { settings, recent, statusbar, ribbon, plot } →
<config>/settings.json (pretty JSON), load()/save().
- Make UserSettings, StatusBarConfig/StatusPill, CollapseMode and
PlotDialogState serde-derived; #[serde(skip)] marks the plot dialog's runtime
fields so only print preferences persist. Their bespoke .txt load/save is
removed.
- App gains current_config/apply_config/save_config: one AppConfig::load at
startup distributes into live state; every settings-change site
(persist_settings_if_changed, recent add/remove/limit, status-bar pill
toggle, ribbon density, plot commit) routes through save_config, which diffs
against the last write to avoid thrashing.
- Clean start: the old flat files are ignored (no migration). ocad.pgp stays a
separate hand-editable file.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 16:41:34 +03:00
|
|
|
serde = { version = "1", features = ["derive"] }
|
2026-06-15 01:36:04 +03:00
|
|
|
# Stable, dependency-free add-on contract (manifest + ribbon/CadModule types).
|
|
|
|
|
# Plugin authors target this crate's semver, not OpenCADStudio internals.
|
2026-06-25 14:11:18 +03:00
|
|
|
# The `host` feature (out-of-process plugin runtime: interprocess, libloading,
|
|
|
|
|
# memmap2, rkyv) is native-only — see the per-target sections below; the web
|
|
|
|
|
# build gets the dependency-free manifest/ribbon contract.
|
2026-06-04 02:34:56 +03:00
|
|
|
# vtkio (pulled in transitively via truck-meshalgo) depends on xz2 → lzma-sys,
|
|
|
|
|
# which by default links the system liblzma dynamically. On macOS that bakes a
|
|
|
|
|
# Homebrew dylib path (/opt/homebrew/.../liblzma.5.dylib) into the binary, so
|
|
|
|
|
# the .app crashes on launch on machines without that exact library (#56).
|
|
|
|
|
# Forcing the `static` feature builds liblzma from the bundled source, making
|
|
|
|
|
# the binary self-contained on every platform.
|
2026-06-16 13:01:19 +03:00
|
|
|
lzma-sys = { version = "0.1", features = ["static"], optional = true }
|
2026-06-16 03:46:24 +03:00
|
|
|
iced = { version = "0.14", features = ["image", "svg", "advanced", "canvas", "smol"] }
|
2026-05-23 22:21:30 +03:00
|
|
|
bytemuck = { version = "1.25", features = ["derive"] }
|
|
|
|
|
glam = { version = "0.33", features = ["bytemuck"] }
|
2026-03-22 14:56:27 +03:00
|
|
|
truck-modeling = "0.6"
|
2026-06-16 13:01:19 +03:00
|
|
|
truck-meshalgo = { version = "0.4", default-features = false, features = ["tessellation"], optional = true }
|
2026-03-22 14:56:27 +03:00
|
|
|
truck-polymesh = "0.6"
|
2026-05-23 22:21:30 +03:00
|
|
|
rfd = "0.17"
|
2026-06-20 13:59:20 +03:00
|
|
|
# Command-line parsing: file arg, --serve/--export/--script and the headless flags.
|
|
|
|
|
clap = { version = "4", features = ["derive"] }
|
|
|
|
|
# Opt-in logging via --log / RUST_LOG (surfaces wgpu / iced / winit diagnostics).
|
|
|
|
|
env_logger = "0.11"
|
2026-06-26 07:00:36 +03:00
|
|
|
acadrust = "0.4"
|
2026-07-11 01:27:17 +03:00
|
|
|
# Shared DWG embedded-preview extraction (Start-page + file-manager thumbnails).
|
|
|
|
|
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
|
2026-04-06 14:37:23 +03:00
|
|
|
flate2 = "1"
|
2026-04-06 23:19:08 +03:00
|
|
|
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "bmp", "tiff"] }
|
2026-05-26 22:45:54 +03:00
|
|
|
inventory = "0.3"
|
2026-06-16 13:01:19 +03:00
|
|
|
truck-shapeops = { version = "0.4", optional = true }
|
2026-06-05 00:35:53 +03:00
|
|
|
# Fast non-cryptographic hasher. Handle/u64 keys dominate the hot block,
|
|
|
|
|
# hatch, draw-depth and wire caches; the default SipHash is overkill there.
|
|
|
|
|
rustc-hash = "2"
|
2026-06-16 11:18:17 +03:00
|
|
|
# TrueType/OpenType support: fontdb enumerates the user's installed system
|
|
|
|
|
# fonts; ttf-parser extracts glyph outlines we flatten into CAD wire strokes.
|
|
|
|
|
# Both are already in the tree transitively via iced's cosmic-text, so pinning
|
|
|
|
|
# them here adds no new downloads.
|
|
|
|
|
fontdb = "0.23"
|
|
|
|
|
ttf-parser = "0.25"
|
|
|
|
|
# Full text-layout engine: shaping (ligatures, Arabic joining, kerning), bidi
|
|
|
|
|
# reordering, and — crucially — automatic font fallback (a glyph missing from
|
|
|
|
|
# the chosen family is shaped from another installed font). We use it only to
|
|
|
|
|
# obtain positioned (font, glyph-id) runs; outlines come from ttf-parser and
|
|
|
|
|
# render through our own wire pipeline.
|
|
|
|
|
cosmic-text = "0.15"
|
2026-06-25 18:17:01 +01:00
|
|
|
lyon_tessellation = "1.0.20"
|
2026-04-22 22:22:33 +03:00
|
|
|
|
|
|
|
|
[target.'cfg(target_os = "windows")'.dependencies]
|
2026-06-12 08:00:18 +00:00
|
|
|
# Win32_System_Com — COM behind "Set as default app"
|
|
|
|
|
# (IApplicationAssociationRegistrationUI dialog).
|
|
|
|
|
# Win32_System_Registry — HKCU registration that lists the app under
|
|
|
|
|
# "Open with" for the portable .exe.
|
|
|
|
|
windows-sys = { version = "0.61", features = ["Win32_UI_Shell", "Win32_UI_WindowsAndMessaging", "Win32_System_Com", "Win32_System_Registry", "Win32_Foundation"] }
|
2026-05-01 08:04:35 +03:00
|
|
|
|
|
|
|
|
[patch.crates-io]
|
2026-07-15 07:55:27 +03:00
|
|
|
# The `acadrust` crate now tracks the OpenAEC-Foundation/acadifc fork's main
|
|
|
|
|
# (still the `acadrust` package): the in-flight DWG reader work plus the Arc
|
|
|
|
|
# copy-on-write entity storage that makes the undo document clone cheap. Drop the
|
|
|
|
|
# patch once these land in a published 0.4 crate.
|
|
|
|
|
acadrust = { git = "https://github.com/OpenAEC-Foundation/acadifc", branch = "main" }
|
2026-06-16 13:01:19 +03:00
|
|
|
|
|
|
|
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
2026-06-25 14:11:18 +03:00
|
|
|
# Native enables the plugin host runtime (out-of-process plugins).
|
|
|
|
|
ocs_plugin_api = { path = "crates/ocs_plugin_api", features = ["host"] }
|
2026-06-16 17:11:20 +03:00
|
|
|
rayon = "1"
|
2026-06-16 13:01:19 +03:00
|
|
|
open = "5"
|
2026-06-25 14:11:18 +03:00
|
|
|
# PDF export / printing. Native-only: printpdf pulls a wasm-incompatible
|
|
|
|
|
# `memchr` (1.0.2) via lopdf → nom_locate, and the web build has no filesystem.
|
2026-06-28 17:26:55 +01:00
|
|
|
printpdf = { version = "0.9.1", default-features = false }
|
2026-06-16 13:01:19 +03:00
|
|
|
ureq = { version = "3", default-features = false, features = ["rustls"] }
|
2026-06-16 13:16:35 +03:00
|
|
|
|
|
|
|
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
2026-06-25 14:11:18 +03:00
|
|
|
# Web gets the dependency-free manifest/ribbon contract only (no plugin host).
|
|
|
|
|
ocs_plugin_api = { path = "crates/ocs_plugin_api" }
|
2026-06-16 13:16:35 +03:00
|
|
|
console_error_panic_hook = "0.1"
|
2026-06-25 14:11:18 +03:00
|
|
|
# ahash (via acadrust) pulls getrandom 0.3, which needs the `wasm_js` backend
|
|
|
|
|
# enabled to support wasm32-unknown-unknown (plus the matching rustflag in
|
|
|
|
|
# .cargo/config.toml).
|
|
|
|
|
getrandom = { version = "0.3", features = ["wasm_js"] }
|
2026-06-17 00:52:20 +03:00
|
|
|
wasm-bindgen = "0.2"
|
feat(web): lazy per-script font loading for international CAD text
The web build has no system-font access, so CAD text in non-Latin scripts
(Cyrillic, Greek, CJK, …) rendered as nothing — build_fallback was a hard
None on wasm (#141). Instead, ship per-script Noto subsets under web/fonts
(one alphabet per file, SIL OFL 1.1) and fetch them lazily over HTTP the
first time a drawing uses that script, then outline glyphs with ttf-parser.
- web_font: Script enum + script_of (char → script font), a per-script
store with lazy fetch, and a pending queue drained by the app loop.
- CJK is split by language (chinese/japanese/korean). Han ideographs share
code points but differ by language, so the shared block is routed by the
document's $DWGCODEPAGE (932→JP, 949→KR, GB/936→CN); kana is always
Japanese, Hangul always Korean. Re-tessellates when the language changes.
- build_fallback (wasm) outlines from the fetched subset; clear_fallback_cache
lets glyphs that missed while a font was in flight reappear on load.
- PollWebFonts subscription (web only) + WebFontLoaded message drive fetches.
- Trunk copy-dir serves web/fonts; nothing is bundled into the native binary
(desktop keeps using system fonts).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 16:13:26 +03:00
|
|
|
# fetch() returns a JS Promise; bridge it to a Rust future for the per-script
|
|
|
|
|
# web font loader (#141).
|
|
|
|
|
wasm-bindgen-futures = "0.4"
|
2026-06-17 00:52:20 +03:00
|
|
|
js-sys = "0.3"
|
feat(web): lazy per-script font loading for international CAD text
The web build has no system-font access, so CAD text in non-Latin scripts
(Cyrillic, Greek, CJK, …) rendered as nothing — build_fallback was a hard
None on wasm (#141). Instead, ship per-script Noto subsets under web/fonts
(one alphabet per file, SIL OFL 1.1) and fetch them lazily over HTTP the
first time a drawing uses that script, then outline glyphs with ttf-parser.
- web_font: Script enum + script_of (char → script font), a per-script
store with lazy fetch, and a pending queue drained by the app loop.
- CJK is split by language (chinese/japanese/korean). Han ideographs share
code points but differ by language, so the shared block is routed by the
document's $DWGCODEPAGE (932→JP, 949→KR, GB/936→CN); kana is always
Japanese, Hangul always Korean. Re-tessellates when the language changes.
- build_fallback (wasm) outlines from the fetched subset; clear_fallback_cache
lets glyphs that missed while a font was in flight reappear on load.
- PollWebFonts subscription (web only) + WebFontLoaded message drive fetches.
- Trunk copy-dir serves web/fonts; nothing is bundled into the native binary
(desktop keeps using system fonts).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 16:13:26 +03:00
|
|
|
# window.open (external URLs) + Blob/anchor file downloads (Save) + fetch()
|
|
|
|
|
# (Response) for the lazy per-script web font loader (#141).
|
2026-06-17 00:52:20 +03:00
|
|
|
web-sys = { version = "0.3", features = [
|
|
|
|
|
"Window",
|
2026-06-17 01:33:54 +03:00
|
|
|
"Navigator",
|
2026-06-17 00:52:20 +03:00
|
|
|
"Document",
|
|
|
|
|
"Element",
|
|
|
|
|
"HtmlAnchorElement",
|
|
|
|
|
"Blob",
|
|
|
|
|
"Url",
|
feat(web): lazy per-script font loading for international CAD text
The web build has no system-font access, so CAD text in non-Latin scripts
(Cyrillic, Greek, CJK, …) rendered as nothing — build_fallback was a hard
None on wasm (#141). Instead, ship per-script Noto subsets under web/fonts
(one alphabet per file, SIL OFL 1.1) and fetch them lazily over HTTP the
first time a drawing uses that script, then outline glyphs with ttf-parser.
- web_font: Script enum + script_of (char → script font), a per-script
store with lazy fetch, and a pending queue drained by the app loop.
- CJK is split by language (chinese/japanese/korean). Han ideographs share
code points but differ by language, so the shared block is routed by the
document's $DWGCODEPAGE (932→JP, 949→KR, GB/936→CN); kana is always
Japanese, Hangul always Korean. Re-tessellates when the language changes.
- build_fallback (wasm) outlines from the fetched subset; clear_fallback_cache
lets glyphs that missed while a font was in flight reappear on load.
- PollWebFonts subscription (web only) + WebFontLoaded message drive fetches.
- Trunk copy-dir serves web/fonts; nothing is bundled into the native binary
(desktop keeps using system fonts).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 16:13:26 +03:00
|
|
|
"Response",
|
2026-06-20 17:05:02 +03:00
|
|
|
# Async clipboard read for paste into the text/MText editors (iced's own
|
|
|
|
|
# clipboard read is a no-op on the web).
|
|
|
|
|
"Clipboard",
|
2026-06-17 00:52:20 +03:00
|
|
|
] }
|
2026-06-16 17:53:56 +03:00
|
|
|
# Browsers without WebGPU (e.g. Firefox by default) need wgpu's WebGL2 backend;
|
|
|
|
|
# `webgl` enables it. `fira-sans` embeds the default UI font — the web has no
|
|
|
|
|
# system fonts, so without it all iced text (ribbon labels, command line) is
|
|
|
|
|
# blank. Features merge with the main `iced` dependency.
|
|
|
|
|
iced = { version = "0.14", features = ["webgl", "fira-sans"] }
|
2026-07-09 02:24:38 +03:00
|
|
|
|
|
|
|
|
[profile.release]
|
|
|
|
|
strip = true
|