Commit Graph
779 Commits
Author SHA1 Message Date
Eric Kaden 8f292c66ae M6: scripts see xfa_version, and xfa_installed in XFA forms (#4142) 2026-10-23 10:19:09 -04:00
Combiler01 3641801f13 Fixes: Refactored System not opening for Added/Pasted Images 2026-10-23 14:49:01 +05:30
Jayesh-Prajapati9 d9115bb90b M7: edited text keeps every space typed (#4199, #3797)
Rewriting a paragraph in one style split its text at white space and
joined the words with one space, so a run of spaces, an indent or a
trailing space typed in the editor was saved as one space or none. The
text is now kept as typed (other white space becomes a space, and CR or
CRLF become line breaks), and the wrapper keeps each run of spaces,
dropping only the spaces where a row wraps.

A justified (stretched) row still drops its indent and the spaces after
its last word, as before, so word spacing reaches only the spaces
between its words; keeping an indent on a justified row is a possible
follow-up. Centred and right-aligned rows, and the editor's draft box,
are measured to the last word, and a paragraph at 0 Tz is not justified.

Fixes #4199
Fixes #3797
2026-10-23 13:50:17 +05:30
Guillem Hermida 558fa0c995 Merge remote-tracking branch 'origin/main' into fix/2583-note-icon-no-rotate
# Conflicts:
#	ROADMAP.md
#	crates/annot/src/lib.rs
#	crates/automation/src/comments.rs
#	crates/engine/src/lib.rs
#	crates/engine/src/tests.rs
#	crates/render/src/inspect.rs
#	crates/ui-egui/src/canvas.rs
#	crates/ui-egui/src/comments_panel.rs
#	crates/ui-egui/tests/it/comments.rs
#	parity/acrobat-features.toml
#	vendor/README.md
2026-10-23 10:19:47 +02:00
Combiler01 e4476b007d Fix:Added Image don't follow the Refactored Edit_image 2026-10-23 13:08:57 +05:30
Osvaldo DuranandClaude Opus 5.5 4ebf287e61 Merge upstream main 0dc77fe4 into pr/attachments
crates/organize/src/import.rs: upstream's name_tree_entries (seen-node set, each node read once) kept whole; this PR's only change to it, pub(crate) for attachments.rs, applied on top.
crates/organize/src/attachments.rs: its name_tree_entries call passes the new seen set.
crates/automation/tests/attachment_key.rs, crates/ui-egui/tests/attach_picker_target.rs: moved into tests/it/ and registered in main.rs, following upstream's one-binary layout (organize keeps its single test file, as upstream's rule says).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 03:15:10 -04:00
mtlcl410andClaude Opus 5.5 adc8307c0b M6: a saved Password field returns to its default value and is redrawn from it (#3926)
Review on #3943. A black-box test of Acrobat (synthetic form, Save As and
Ctrl+S, every decoded object searched) showed how it saves a Password
field: the typed value is nowhere in the file; a field with /DV is saved
holding /DV, one without is left empty; the asterisks are drawn from the
saved value (5 for a 5-letter default, not 13 for the typed password);
/DV and /AA are kept.

clear_password_values now does the same: it restores the (inherited)
/DV as the value, or leaves the field empty, and redraws the widgets, so
the appearance no longer shows how long the typed password was. A field
already at its default no longer counts as holding a password, so such
a form needs no cleaned copy. The parity note for form.fill-text says so
and lists the two limits Acrobat shares (a script copying the password
into an ordinary field, and an earlier revision kept by an incremental
save).

Mutants, each failing a test: no /DV restore, no redraw, the default
ignored in password_fields, emptiness ignored (an empty string in an
array). Dropping the empty-default filter was equivalent, so the filter
is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 14:38:29 +08:00
mtlcl410andClaude Opus 5.5 64c5fd8ef0 M6: signing, timestamping and DSS writes carry no Password-field values (#3926)
CodeRabbit on #3943: sign, sign_with_timestamp, timestamp_document and dss::embed
each write a new incremental file from editor.cos, outside the writable() boundary
saves use, so a typed Password value was signed into the file. Each now writes from
the writable() copy. The new test signs a form with a typed value and checks the
signed file holds the masked appearance but not the value; the three TSA/DSS paths
need a timestamp server or validation data, and use the same one-line change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 14:38:29 +08:00
mtlcl410andClaude Opus 5.5 048cf14d31 M6: Extract, Split and Combine write no Password-field values either (#3926)
CodeRabbit on #3943: Extract Pages copies the fields of the pages it takes, and
write_new (Combine, Extract, Split, Create) wrote that copy without the writable()
boundary saves use, so the new file kept a typed Password value. write_unchecked, which
write_new and Split's size measuring both go through, now writes the sanitized copy. The
other write_full/write_incremental calls in the engine build in-memory bytes (display,
previews, the working copy, print rasters), not files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 14:38:29 +08:00
mtlcl410andClaude Opus 5.5 0e883c44a0 M6: values typed into Password fields are written to no file (#3926)
A text field with the Password flag kept its typed value in /V, so Save, a full
rewrite, Reduce File Size and the recovery snapshots all wrote it in plain text.
ISO 32000-2 §12.7.5.3, Table 231 (note to the Password flag): PDF processors
should never store the value in the PDF file. Each of those paths now writes a
copy without the values; the open document keeps them in memory, and the masked
appearance is kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 14:38:16 +08:00
Combiler01 91c575b1df Merge remote-tracking branch 'upstream/main'
# Conflicts:
#	crates/edit/src/images.rs
#	crates/engine/src/tests.rs
#	crates/xfa/src/script.rs
2026-10-23 11:08:12 +05:30
Combiler01 2a9f7eb862 Fixes suggested by Reviewers 2 2026-10-23 10:28:47 +05:30
Eric Kaden 8f82bfccec Merge remote-tracking branch 'upstream/main' into fix/exec-menu-attachments
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-22 23:09:22 -04:00
Eric Kaden cf2f4ec766 Merge remote-tracking branch 'upstream/main' into fix/xfa-edit-picture-alternatives
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-22 22:55:12 -04:00
songzhihui addb876297 M2: continue CJK viewer fallback for Windows GBK PDFs 2026-10-23 10:49:08 +08:00
Eric Kaden dd6d7feadb M12: a date is tried in the field's first pattern again only when its format refused it 2026-10-22 22:18:11 -04:00
Eric Kaden 91df3c01a8 Merge remote-tracking branch 'upstream/main' into fix/xfa-edit-picture-alternatives
# Conflicts:
#	crates/xfa/src/tests.rs
2026-10-22 21:54:56 -04:00
Osvaldo DuranandClaude Sonnet 5.5 fd8d402e30 Merge upstream main 39844f06 into pr/attachments
Merged cleanly, no conflicts.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 21:45:25 +00:00
aiongg 35b5abd5b3 test(engine): show the truncated-page picture exports within a sufficient budget
The fixture's image stream held six bytes under /Length 4, and the test
only checked that the picture was missing at a zero budget, which a
picture that could not be prepared also passes. The stream is four
bytes, and the picture is first shown to export at a 1 MiB budget.
2026-10-22 21:42:02 +00:00
magdale76andClaude Opus 5.5 6996aac44a M3: Document Properties shows a title and author stated only in XMP (#2373)
Description read Title, Author, Subject and Keywords only from /Info. A file
that states them only in its XMP packet (/Info is deprecated in PDF 2.0, and
some writers leave it out) showed empty fields, while Acrobat shows them.
organize::info now falls back to the packet's dc:title, dc:creator,
dc:description, pdf:Keywords, xmp:CreatorTool and pdf:Producer: a language
alternative gives its x-default item, and several authors are joined with
"; ". The engine fills the inspection's missing fields the same way, so the
read-only Description rows and doc_info agree with the editable fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 23:33:26 +02:00
aiongg aa1c13f71c fix(engine): list a page truncated for both forms and pictures once 2026-10-22 20:56:02 +00:00
aiongg 923e499597 Merge upstream/main into fix/coderabbit-c5-forms-misc
Conflict in crates/content/src/lib.rs: main ends inline images where the
renderer's tokenizer ends them and counts the images whose end is a guess
(Parsed::ambiguous_images); this branch reads operators through the
streaming Ops iterator that parse collects. The iterator's BI branch takes
main's inline_image result and keeps the ambiguous-image count, which parse
copies into Parsed and Ops::ambiguous_images reports.
2026-10-22 20:51:14 +00:00
aiongg b72078871a fix(content): end inline images where the renderer ends them
Filtered inline image data has no length, so its end is an EI chosen
among candidates, and the content parser chose by a different rule
than the renderer's tokenizer (hayro-syntax): the renderer also takes an
EI with no whitespace before it, and checks a candidate by reading what
follows as operators. With image data such as "7FEI 1 0 0 1 200 0 cm",
the renderer ran a cm that redaction read as image data, so text was
drawn 200 pt from where removal and its verify pass looked.

The parser now takes each inline image's end from the renderer's
tokenizer (already in the tree through pdfcraft-cos), so both read the
same operators after the image; a test runs both on the same fixtures.
Only where that tokenizer reads no image (no EI it accepts, or
parameters it can't read) does the parser fall back to its own rules,
counting the image in Parsed::ambiguous_images, and applying redactions
refuses such a page as unreadable.
2026-10-22 15:17:44 -04:00
aiongg 22aa6d5f9a fix(redact): place glyphs with the inherited and ExtGState-set text state
The redaction interpreter started every form XObject with an empty text
state (no font, size 0, no spacing) although a form inherits its caller's
graphics state, and it ignored the /Font entry of an ExtGState set by gs.
Text shown that way was placed at the wrong positions, so removal and
the verify pass could both miss glyphs under a mark. Forms now start
from the caller's state, and gs sets the font and size as Tf does.

The engine's renderer cross-check test used the gs case as its example
of interpreter/renderer disagreement; it now runs the check directly on
an unredacted page, which also covers an input stream labelled as a
redaction overlay.
2026-10-22 15:17:44 -04:00
aiongg 6ca4431b50 fix(redact): check every input content stream, whatever it calls itself
Both checks for text left under applied redaction marks (redaction's own
verify pass and the engine's renderer cross-check) skipped any page
content stream whose dictionary said /PCMark /Redaction, so that the
overlay's label would not count. An input file could put that label on
its own content stream and keep it out of both checks. Applying
redactions now records the overlay streams it adds (stamp returns the
new stream), and only those are skipped.
2026-10-22 15:17:44 -04:00
Osvaldo DuranandClaude Sonnet 5.5 542196d907 Merge upstream main 3e968c8a into pr/attachments
Mechanical merge (ATTRIBUTION.toml): main's copy of the pinned files, hashes recomputed, both sides' catalog rows kept.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 18:55:02 +00:00
Combiler01 dea68e6350 Fixes Suggest by Reviewers 2026-10-23 00:21:21 +05:30
aiongg f2f86455dd fix(engine): read long underscore runs in one pass
Word assembly checked whether the whole word so far was underscores for
every glyph it added, so a long run of underscores on one line took
quadratic time. The underscore state of the current word is kept as it
grows.
2026-10-22 18:02:33 +00:00
aiongg 467c8556ec fix(engine): encode each image once for Office export
Office export encoded and kept a separate copy of an image for every place
a page drew it, so a short content stream repeating Do on one large image
multiplied it into gigabytes before the writers' limits applied. Each image
object is now encoded once and its bytes shared (pdfcraft_export::Image
holds an Arc<[u8]>), distinct pictures share a 512 MiB budget whose
overflow lists the page as truncated, and RTF, which leaves pictures out,
prepares none.
2026-10-22 18:02:33 +00:00
Combiler 5c8db57e5c Merge branch 'storytold:main' into main 2026-10-22 17:32:38 +00:00
PerchAnton c5279baf35 M6 PR #2648: retain active-XFA script isolation with current main 2026-10-22 20:21:39 +03:00
aiongg 77480498b2 fix(engine): low-resolution printing prints only the chosen content
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.
2026-10-22 13:18:26 -04:00
aiongg 73f11b2a29 fix(engine): fail an action whose information-removal step fails
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.
2026-10-22 13:18:26 -04:00
aiongg 28ab616eb6 fix(engine): print as low-resolution pictures when only that is allowed
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.
2026-10-22 13:18:26 -04:00
aiongg 30300ae71b fix(engine): compare only documents that allow copying their text
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.
2026-10-22 13:18:26 -04:00
alehel 5db4480b40 Merge remote-tracking branch 'origin/main' into fix/background-hidden-by-page-backdrop
# Conflicts:
#	parity/acrobat-features.toml
2026-10-22 18:04:34 +02:00
Osvaldo DuranandClaude Sonnet 5.5 f84d6b17e6 Merge upstream main 95263631 into pr/attachments
Merged cleanly, no conflicts.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 15:48:35 +00:00
alehel 845642691f Merge remote-tracking branch 'origin/main' into feat/all-tools-expand-view 2026-10-22 17:32:21 +02:00
Eric Kaden 9206174761 Merge remote-tracking branch 'upstream/main' into fix/xfa-layout-drops-usage-rights
# Conflicts:
#	parity/acrobat-features.toml
2026-10-22 11:31:44 -04:00
Eric Kaden e646bb8684 Merge remote-tracking branch 'upstream/main' into fix/exec-menu-attachments
# Conflicts:
#	parity/acrobat-features.toml
2026-10-22 11:31:44 -04:00
Combiler01 7d2b02633c Merge remote-tracking branch 'upstream/main' 2026-10-22 21:01:36 +05:30
aiongg 9526363152 Build each crate's integration tests as one binary (#4087)
* 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.
2026-10-22 11:28:58 -04:00
jonathanwxh-cell 17f84e4391 Merge main into feat/optimize-compatibility-version
Retain compatibility regression coverage with upstream content-boundary and image-size tests.
2026-10-22 21:34:02 +08:00
Ridzzz0Alam bd00a131b6 M6: form_fill warns when a value does not fit its field (#4018)
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
2026-10-22 12:52:40 +02:00
alehelandClaude Opus 5.5 8d1d7b11d5 Merge remote-tracking branch 'origin/main' into feat/all-tools-expand-view
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>
2026-10-22 12:26:42 +02:00
alehelandClaude Opus 5.5 2358430e79 Merge remote-tracking branch 'origin/main' into fix/background-hidden-by-page-backdrop
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>
2026-10-22 12:20:28 +02:00
Osvaldo DuranandClaude Sonnet 5.5 6a5e6728e0 Merge upstream main 9a0ec645 into pr/attachments
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>
2026-10-22 09:50:52 +00:00
jonathanwxh-cell c05f00c67a fix(engine): generate Protect keys and salts with getrandom (#4000) 2026-10-22 16:07:14 +08:00
Combiler01 4d93503937 Merge remote-tracking branch 'upstream/main'
# Conflicts:
#	ATTRIBUTION.toml
#	crates/automation/src/tools.rs
#	crates/automation/tests/automation.rs
#	crates/edit/src/images.rs
#	crates/edit/src/lib.rs
#	crates/edit/src/tests.rs
#	crates/engine/src/lib.rs
#	crates/ui-egui/src/create_ui.rs
#	crates/ui-egui/src/edit_text_ui.rs
#	crates/ui-egui/src/editing.rs
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/tests/content.rs
#	crates/ui-egui/tests/editing.rs
2026-10-22 13:32:03 +05:30
Eric Kaden 4665685446 Merge remote-tracking branch 'upstream/main' into fix/exec-menu-attachments
# Conflicts:
#	crates/engine/src/tests.rs
#	crates/js/src/tests.rs
#	crates/ui-egui/tests/forms.rs
2026-10-22 03:19:20 -04:00