Pages printed as pictures were drawn with everything on them, so form fields only
printed the page content, and the document with stamps printed every comment. The
pictures are drawn from a copy holding only what the vector print draws.
A step that applies an edit logged any error and carried on, which is right
for a flatten with nothing to flatten but not for removing hidden
information or sanitizing: on a signed file the removal was refused, and the
unchanged file was written out as the action's successful result. Those
steps now fail the action unless there was nothing to remove.
Printing checked the print permission but not the separate high-quality one
(Table 22, bit 12), so a document limited to low-resolution printing came out
as its original vector pages, text included. Such a document now always
prints as pictures of at most 150 dpi, whatever the settings ask for.
Compare read both documents' words out with no check of the copying
permission, and its result, report and difference comments carry that text,
so a copy-restricted document's text could be taken out through a comparison.
Both documents must now allow copying.
* Build each crate's integration tests as one binary
Every tests/*.rs file is its own executable that links the whole crate
graph. Move each crate's test files into tests/it/ as modules of one
tests/it/main.rs, for apps/pdfcraft, apps/pdfcraft-cli, automation, cos,
crypt, engine, render, sign and ui-egui. ui-egui's ui_group binary and
the support modules move into tests/it/ too. Crates with a single test
file keep it. The test executables go from 150 to 52, and every crate
runs the same number of tests as before.
ui-egui perf keeps its own binary (own process): its frame-time budgets
would charge each measurement for the other tests running beside it.
What the move needs:
- include_str!/include_bytes! and #[path] paths gain one "../".
- ui-egui: one GPU lock in tests/it/main.rs replaces the five per-file
ones (content, document_links, editing, fill_sign, view), so one
process creates one wgpu device at a time. The drop-line test in ui.rs
and the screenshot blocks behind PDFCRAFT_*_SHOT(S) and
CRAFT_UI_DOCKING_DIR, which render without holding it, take it too.
- pdfcraft winit_wayland_scroll: the vendored winit source it compiles
names crate::event, so that shim lives in main.rs.
- parity evidence names the new paths.
* Name the one-binary test paths in docs and comments
- READMEs, docs, ATTRIBUTION and source comments name tests/it/<file>.rs.
- The oracle README's example filters with --test it encryption::qpdf_agrees.
- pdfcraft's GPU lock comment points at the UI tests' shared lock in
crates/ui-egui/tests/it/main.rs.
With a fixed font size, a text field's appearance cuts a long value at
the edge of its box, but form_fill only answered "filled": n. A person
sees the cut; an agent filling forms through the CLI or MCP did not.
The text appearance builder now notes when the text it lays out does
not fit: one line wider than the box, or wrapped lines below it.
forms::appearance::value_overflow asks that for a field's widget,
Document::field_overflow for a field by name, and form_fill adds a
warning for each filled field that is cut off. The value is still saved
whole and drawn as before; auto-sized fields shrink to fit and are not
reported.
The automation tests' inline PDF builder moves to a shared pdf_of.
Fixes#4018
Conflicts:
- crates/ui-egui/src/panels.rs: main made `panel_header` pub(crate) with
`back: Option<&str>` (the Calculation order page uses it too); this branch
needs its leading button to be Expand on All tools. It now takes
`lead: Option<(&str, &str)>`, the button's icon and tooltip, and the three
callers pass theirs (calc_order_ui.rs included).
- i18n catalogues: both sides appended entries at the same place; kept both.
- ATTRIBUTION.toml: catalogue hashes recomputed.
Main added eleven catalogues since this branch was cut (ca, ckb, fi, hi, id,
ko, lo, nb, ro, sq, th), and their coverage tests require every UI literal, so
the eight All tools view strings are translated in them too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts:
- crates/edit/src/lib.rs: keep both `backdrop` (this branch) and main's new
`background` module (#2992, page background colour for Export to Word).
- crates/engine/src/lib.rs, crates/ui-egui/src/marks_ui.rs: union of the
imports (main added BlockKey, block_overlapping and FontFamily).
- ATTRIBUTION.toml: catalogue hashes recomputed.
Main added eleven catalogues since this branch was cut (ca, ckb, fi, hi, id,
ko, lo, nb, ro, sq, th), and their coverage tests require every UI literal, so
the six Add Background backdrop messages are translated in them too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolved by the keeper:
- ATTRIBUTION.toml: upstream's copy, hashes recomputed
- crates/organize/src/tests.rs: additions from both sides, upstream's first
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* M14: add Norwegian Bokmål interface and date language
A 2,592-entry `nb.tsv` covering every key the other bundled catalogs have,
written from the meaning of the English labels (clean-room); terminology
reviewed by a native-speaking contributor. Registers `nb` with the English
one/other plural rule, adds Norwegian month and weekday names for Fill &
Sign dates, resolves `no` and `nn` locales to Bokmål until a Nynorsk catalog
exists, attributes the catalog and records it in parity.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* M14: translate the strings main added since the Norwegian catalog was written
69 keys (signature appearance labels, word count, full-screen prompt, print
as image, image crop, redaction mark appearance, …) and the attribution hash.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* M14: translate the picture-menu and label-paper strings in the Norwegian catalog
Seven keys main added (Cut/Redact Image, Create Link…, Recognize Text…,
Turn upside down, the 4 x 6 in label paper) and the attribution hash.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* M14: translate the page-group folding commands in the Norwegian catalog
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* M14: drop the superseded localization summaries left beside the current ones
Concurrent merges on main left older copies of several localization
summaries next to their replacements. Review of #1836 flagged them:
- localization-parity.md: remove the 2026-10-13 status line and the
14-language summary that still listed Norwegian as missing; the
current summary keeps the Italian (and now Norwegian Bokmål)
measurement dates.
- localization.md: keep one catalog-coverage paragraph (now naming
Norwegian Bokmål, up to about 2,700 entries) and one font paragraph.
The font paragraph folds in what only the older copies said: the
installed Chinese face fallback (#826) and Slovenian's Latin faces and
four plural forms.
- roadmap.md: end the M14 Missing list before the Fontconfig note.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
Co-authored-by: aiongg <aiongtaigi@gmail.com>
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: arrays sized 30.
ATTRIBUTION.md: both sides' rows; count regenerated after all merges.
docs/localization.md: main's text with the ckb name, code and catalog-list entry added.
DATE_LANGUAGES gains the lo row in the same position as in LANGUAGES, so
date_languages_are_the_interface_languages holds; lo.tsv loses a key that
matches no English source.
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows, arrays sized 28.
crates/ui-egui/tests/fonts.rs: both catalog lists.
ATTRIBUTION.md: both sides' rows; count regenerated after all merges.
ROADMAP.md: main's summary with Romanian added (15 more catalogs); both log lines.
docs/localization-parity.md: main's rows plus the ro row; 28 interface languages; both revision rows.
docs/localization.md: main's text with Română, the ro locales and code, and the PR's catalog-list edits.
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows, arrays sized 27.
crates/ui-egui/tests/fonts.rs: both catalog lists; Catalan added to main's comment.
ATTRIBUTION.toml/.md: both sides' assets; hashes and counts regenerated after all merges.
ROADMAP.md: both log lines.
docs/localization-parity.md: main's rows plus the ca row; 27 interface languages; both revision rows.
docs/localization.md: main's text with Català, the ca locales, code and catalog paragraph added.
Conflict resolutions:
- ATTRIBUTION.toml: main's entries kept; #3101's page-gap provenance note appended to the 22 catalogs it translates (hashes recomputed separately).
- ATTRIBUTION.md: main's side kept; regenerated from ATTRIBUTION.toml separately.
- ROADMAP.md: #3101's two 2026-10-18 progress-log lines placed after the 2026-10-19 entries.
- docs/roadmap.md: both 2026-10-18 status lines kept; M3 row carries both sides' insertions.
crates/engine/src/dates.rs, crates/ui-egui/src/i18n/mod.rs: both sides' language rows (vi, fi, sq), arrays sized 25.
crates/ui-egui/tests/fonts.rs: both catalog lists; Albanian added to main's comment.
ATTRIBUTION.toml/.md: both sides' assets; hashes and counts regenerated after all merges.
ROADMAP.md: both log lines.
docs/localization-parity.md: main's rows plus the sq row; 25 interface languages; both revision rows.
docs/localization.md: main's text with Shqip, the sq locales and code added.
crates/xfa/src/tests.rs: union of fixture imports (tiny_bmp, tiny_tiff).
parity/acrobat-features.toml: form.xfa and the XFA image entry: evidence lists unioned, notes take both sides' insertions.
Conflicts:
- ATTRIBUTION.toml: ours (sha256 lines only); hashes recomputed at the end of the track
- crates/engine/Cargo.toml: main's workspace chrono entry, plus the PR's pdfcraft-testkit dev-dependency