web: raster images, WBLOCK/SAVEALL/SCRIPT/CTB/LAYTRANS/INSERT, filled TTF text

A fresh web-vs-desktop audit found the remaining gaps; this closes the
top ten.

Raster images: IMAGE attach read the picked file via image::open on a
name-only path (dead on wasm), and raster references inside opened
drawings decoded the same way. Picked bytes are now registered in a
name-keyed store (the PDF-underlay pattern), decoding runs from memory,
and dropped .png/.jpg/.bmp/.tif files register by name so unresolved
references in opened drawings re-resolve and render (and export to PDF).

Command gaps fixed with the bytes-at-pick / download_bytes pattern:
- WBLOCK now downloads the extracted block instead of failing on fs.
- SAVEALL saves every dirty tab instead of printing a no-op message.
- SCRIPT picks and reads the .scr file through the browser picker.
- CENTERLTYPEFILE picks the .lin/.dnl file and populates from text.
- Custom .ctb tables picked on web now parse, register for the
  session, appear in the plot dialog list, and apply (load_named
  previously returned builtin-only on wasm).
- LAYTRANS 'Load standards file' parses the picked drawing on the
  existing web worker.
- INSERT 'from file' in the block palette parses picked bytes and
  feeds the shared import path.

Text fidelity: TTF-named styles rendered as thin stroke glyphs on web
because the font database was empty. Fetched Noto faces are now
registered into it with a family alias table (Arial, Times New Roman,
Cambria, ... -> Noto Sans/Serif), so those styles render filled, shape,
export to PDF as vector fills, and appear in the style picker.
ViewCube labels request semibold again on web.

docs/native-vs-web.md: the hatch and font rows were stale (both work on
web now), the GPU row claimed WebGPU is used where available (the
backend is pinned to OpenGL), and the parallelism row missed the parse
worker — all corrected.
This commit is contained in:
Afonsop committed 2026-09-17 20:59:58 +01:00
1 parent fa7ef87f00
commit c643a10ed9
43 files changed
+3216 -1336

No files matched your search

+18 -13
View File
@@ -11,12 +11,12 @@ browser can't provide. This page lists the differences.
|------|------------------|------------|
| Windowing | Multi-window (`iced::daemon`) | Single window (`iced::application`); dialogs are in-canvas modals |
| 3D solid modeling | Yes | Yes — the geometry kernel is pure Rust |
| Hatch rendering | Yes | **No** — WebGL2 has no vertex-stage storage |
| Fonts | Embedded stroke fonts + system TrueType + shaping + fallback | Embedded stroke fonts only |
| Hatch rendering | Yes | Yes — texture transport when WebGL2 lacks vertex-stage storage |
| Fonts | Embedded stroke fonts + system TrueType + shaping + fallback | Fetched Noto subsets (shaping, fallback, and family aliases) + embedded stroke fonts |
| File open | Native file dialog → path | Browser picker → bytes |
| File save | Path / Save dialog → write to disk | Save dialog → direct browser download |
| Parallelism | Multi-threaded (rayon) | Single-threaded |
| GPU backend | Vulkan / DX12 / Metal (wgpu) | WebGL2 (WebGPU where available) |
| Parallelism | Multi-threaded (rayon) | Main thread + one Web Worker (DWG/DXF parse, hashing) |
| GPU backend | Vulkan / DX12 / Metal (wgpu) | WebGL2 (the backend is pinned to OpenGL) |
| Update check / external links | `ureq`, `open` | skipped / `window.open` |
| External plugins | Native packages + Plugin Manager | **No** — native libraries cannot run in a browser |
@@ -33,21 +33,26 @@ all, so none of that applies and the feature is gone. The web build makes
primitives, runs booleans, draws ACIS solids read from a file and writes them
back out as exact geometry, exactly as the desktop build does.
### Hatch rendering — web: not drawn
### Hatch rendering — web: same modes via a texture transport
The batched hatch pipeline binds a read-only storage buffer in the vertex
stage. WebGL2 lacks `VERTEX_STORAGE`, so that pipeline is skipped on wasm and
hatches simply don't render. Everything else (lines, arcs, polylines, text,
images) draws normally.
stage, which WebGL2 lacks. The hatch renderer selects its texture backend
instead (an RGBA32F data texture + `hatch_texture.wgsl`) and draws the same
solid, patterned, and gradient hatches as native, with the same dash math and
sub-pixel-to-solid LOD fallback. Everything else (lines, arcs, polylines,
text, images) draws normally.
### Fonts — web: bundled stroke fonts only
### Fonts — web: fetched Noto subsets plus embedded stroke fonts
- **Native** discovers installed system fonts (fontdb), extracts TrueType
outlines (ttf-parser), shapes runs with cosmic-text (ligatures, Arabic
joining, kerning, bidi), and falls back to a system font for glyphs a stroke
font lacks.
- **Web** has no system fonts, and cosmic-text panics with "no default font
found" on an empty font set, so shaping and fallback are disabled. Only the
embedded LFF stroke fonts render; a glyph missing from them is skipped.
(A future option is to fetch a font file from the server at startup.)
- **Web** fetches per-script Noto subsets from the server, registers them
into the font database, and shapes runs with the same cosmic-text path
(ligatures, Arabic joining, bidi) with per-glyph Noto fallback. Text styles
naming a desktop family (Arial, Times New Roman, ...) resolve through an
alias table to the Noto faces, so they render filled instead of falling to
the stroke fonts; scripts without a fetched subset still render via the
embedded LFF stroke fonts. (Text pops in once the first font fetch lands.)
### File I/O — web: bytes and downloads
- **Open**: the desktop returns a filesystem path and reads it (streaming).