Files
vectorcraft/docs/pdf-backend.md
T
aiongg 714434527e Docking: panels on craft-ui's shared docking, floating panels in OS windows (#4135)
* Build: craft-libs at 2869b8cc

Pin craft-pdf, craft-print, craft-docpath, craft-ui, craft-keymap,
craft-window and the patched hayro/krilla backends to craft-libs
2869b8cc1077530bd07a7e192fb2b0e1304a1354, with the pdf-deps gate,
NOTICE, ASSETS.md and docs/pdf-backend.md at the same revision.

PDF: no modification date beyond the creation date, DeviceN images
are not JPEG-encoded, and clipping text draws nothing (its outlines
arrive as a clip path).

* Docking: compile against craft-ui at 2869b8cc

Floating windows are trees of groups: window_panels and window_active
read one as a flat group, and windows rebuilt from the legacy groups
keep their ids. Unknown dock actions are rejected, the new ones are
checked like the old, and every panel a close action removes keeps its
return location.

* Docking: panels and canvas on craft-ui's docking area

* Docking: tests for the dock area, flyouts, floating panels and the Tools panel

* Docking: catalogs without the old dock's strings

* Build: craft-libs at 8a503cfe

* Docking: floating panels in OS windows of their own on the desktop

* Docking: modal dialogs block panel windows; their keys and dropped files reach the main window

* Docking: art dragged onto a panel in its own window drops there

* Docking: module doc names the OS windows

* Build: craft-libs at a042cf26

* Docking: onto, above, below, collapsed, icon and column places on Float and Dock Panel; ui.docking

* Docking: command descriptions of Float, Dock, Move and Collapse Panel for the craft-ui layout

* Docking: control protocol describes the craft-ui layout, its commands and ui.docking

* Docking: rustfmt

* Docking: layouts saved before the canvas joined convert on load

Saved ui.json files and workspaces from before the shared layout held the
canvas (a dock-only tree plus floating_panels, docking_icons,
docking_collapsed, dock_collapsed and dock_width) convert into one layout:
the dock tree's groups in the main column, the icon column with the panels
dropped on it, floating groups and sets, sets docked as columns, collapsed
groups, the dock width and the places of closed panels. The legacy fields
are read, never written. A ui.json read only in part is copied to
ui.unreadable.json before anything saves over it.

* Docking: catalogs without the old collapse message

* Docking: converted floating sets start at most 720 points tall

* Docking: closed icon panels convert into the icon column; old floating rects, set heights and a copy of the file before conversion

* Build: craft-libs at 27e60765

* Docking: dock column places and icon count from the icon column; a docked column moves to a later place

* Build: craft-libs at d24e4bcc

* Build: craft-libs at 5bbe9f62

* Docs: floating panels in OS windows of their own close the other-monitor gap

* Docking: keys forwarded from a floating panel's OS window run shortcuts while the main window is unfocused
2026-10-25 15:25:35 -04:00

77 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PDF backend
PDF writing uses `craft-pdf` from `storytold/craft-libs`, pinned to
`a0916808f7d78bed8c7b90cdf937176015454a7f`. Its `write` feature supplies Krilla configuration,
metadata construction, fallible font preparation and serialization, and native unwind guards.
The dependency disables default features and enables `write` and `interpret`.
The production writer retains Krilla’s raster-image support without its optional text shaper.
PDF test fixtures enable `simple-text` through a dev dependency.
The PDF crate explicitly retains the `flate2` `zlib-rs` feature previously supplied
by the registry reader, preserving compressed export bytes and their derived document IDs.
VectorCraft owns document traversal, drawing, font selection and embedding policy, colour
conversion, presets, page boxes, layers, editing data, postprocessing and print composition.
Editable import keeps its VectorCraft adapter, layer routing, colour policy and text decisions.
Desktop printer submission remains in `craft-print`.
The shared writer vendors Krilla 0.8.2 with an unwind-safe cleanup and poisoning patch.
The root `[patch.crates-io]` selects that copy from the same immutable revision: Cargo does
not inherit a dependency workspace's patches. A failed page or surface cleanup poisons the
backend document, so serialization cannot return an incomplete PDF after unwinding.
The shared crate's compile-time backend marker and `cargo xtask pdf-deps` (included in CI)
check that the patched writer is used. Krilla retains its MIT OR Apache-2.0 licensing;
its upstream provenance and authored patch are recorded in the shared repository.
Export and print construction, drawing and postprocessing run inside the shared native
unwind guard. These guards do not catch WASM aborts or process-wide allocation failures.
VectorCraft retains its finite-coordinate checks and the existing behavior that omits art
outside the writer's supported coordinate range. Font preparation checks the shared
512 MiB per-font copy limit and variation coordinates before allocation; failure preserves
VectorCraft's reported outline fallback. The writer is not a peak-memory or runtime budget.
PDF reading uses the same shared revision's patched Hayro syntax 0.7.2, interpreter 0.7.0
and JBIG2 0.3.0. This snapshot also retains CCITT 0.3.0 and JPEG 2000 0.3.5.
Its established Lab conversion uses Bradford adaptation; calibrated gray/RGB and tint-function
conversion retain floating-point precision. This policy differs from the registry 0.8 reader's
Lab profile and byte-quantized conversion and is assessed against independent colour expectations.
The application explicitly preserves its existing accepted file sizes with
`OpenOptions { max_input_bytes: usize::MAX, ..Default::default() }`; this migration adds no
new file-size ceiling. Ordinary decoded streams use the shared backend's immutable
per-document limits. Those limits are separate from streaming page-content budgets and
do not bound aggregate document or process memory. Password classification and the
existing permissions-password fallback remain application policy.
The layer and overprint pre-scan consumes `ContentReader` windows through `TypedIter`,
retaining graphics and marked-content state between windows. It does not collect a whole
page before scanning. Reaching the scan's operator, nesting or instruction-window limit,
a reported failed/truncated stream, a cap-reaching filtered form, or an undecidable final
operand tail returns an import error and discards the partial document. Previously the
operator limit could return a partial layer routing with a warning. Interpreter completion
warnings also become errors before a document is returned. Whitespace and comments at
EOF remain valid. The typed iterator does not classify every malformed operator, so this
is known-incomplete rejection rather than a general PDF validity certificate.
The five patched Hayro crates and Krilla are selected in the root `[patch.crates-io]`
from the same immutable revision as `craft-pdf`. `cargo xtask pdf-deps` rejects missing,
duplicate, local-path, registry and mismatched revisions for those seven packages.
`craft-print`, `craft-ui` and the other craft-libs crates use the same revision.
Dependency asset hashes and sources are in `ASSETS.md`; redistributed license texts are
in `licenses/pdf-backend`. Package staging carries those texts together with `NOTICE`
and `ASSETS.md`. Fonts and profiles remain dependency data; this repository adds no font
or profile binaries. Native page interpretation has a shared unwind guard; WASM aborts
and process-wide allocation failures cannot be caught.
The shared parser retains current main's 64-level cap for direct arrays and dictionaries,
including decoded content and object streams. The application retains its two-pass traversal
of repaired object tables, 16-link function/colour-space cap, 64-level calculator-procedure cap,
256 MiB stream checks and predictor validation. Native interpretation uses the existing
16 MiB stack wrapper, and imported document depth remains bounded.
Known incomplete decoded content remains an import error, including deeply nested operands
that the bounded parser cannot finish. Lowered ordinary decode limits and dictionary delimiters
split across scan windows are covered by synthetic regressions; they require the typed
incomplete-content error and never return a partial document. The former 256-level lexical
preflight and its diagnostic are superseded by the parser cap and completion checks.
The scratch bound does not cover whole-filter fallback decoding or aggregate parser/process memory.