chore: sync upstream (214 Commits) #1
No reviewers
Labels
No labels
herkunft/alpha-feedback
status
blockiert
status
zu-testen
typ
bug
typ
docs
typ
enhancement
typ
feature
typ
idea
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
iris/pdfcraft!1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "chore/sync-upstream-20261016"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Upstream-Sync von
upstream/main(214 Commits). Fast-Forward.f0c9901cMerge pull request #2727 from dylanmtaylor/ci/craft-common-actions8fa6fecfci: add nix check workflow5fdd820bfix(ui): validated signature display, snapshot tab reuse (#1895)f65f7330fix(render): faster sampled functions, image decodes across zoom levels and patch meshes (vendored hayro-interpret patches 31–33) (#2436)99941daadocs(roadmap): record the day's two changes50cbf5fafeat(oracle): score reading order, which word F1 cannot see13e3154afix(fonts): read the Annex D.2 alias codes as the ink they drawdc41044bFill Vietnamese and Lithuanian catalog coverage gaps (#2510)609a7242Fix main UI regressions in paging, fonts and test expectations (#2502)5259491cTests: update save and search regressions for current behavior (#2484)491ce2dafix(i18n): zh-hant had two keys twice after concurrent merges (#2414)1bc3a318fix(parity): merge the keys concurrent merges left twice in acrobat-features.toml (#2419)224416a3Tests: the signing test's password meets the 8-character minimum (#2417) (#2420)afa8e184M3: Wayland: stop retaining Ctrl zoom for pixel-only wheel input (#1569)cdf44d79Comments panel: page groups fold from their chevron (#1614)Moving, resizing, rotating or flipping a figure wrapped it in a fresh `q cm … Q` every time, so twenty drags left twenty nested graphics states and twenty `cm` operators around one `Do`. Each edit made the content stream longer and pushed the figure closer to the nesting limit viewers enforce (PDF 32000-1 Annex C recommends 28 levels). When the placement already sits alone in a `q cm … Q` (its own placement, or the wrapper an earlier edit added), `transform_image` and `translate_images` now change that `cm` in place: the CTM inside is `local · cm · outer` either way (8.4.4, 8.3.4), so the result is identical. A bare `cm Do` without a `q`, a shared clip or any other content in the scope still gets the wrapper, once. The new test runs twenty resizes and twenty group moves on a plain placement, one with a crop exclusive to the image, and a bare `cm Do`, and checks the visible rectangle after each step, that the `q` depth stays at its first-edit value, and that the following text is untouched. It fails without this change ("twenty resizes nest no deeper than one"). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>Every call to `embed` or `embed_mapping` wrote a new Type 0 font, CIDFont, descriptor, ToUnicode and glyph map, under a new `PCFull{n}` name. Editing a paragraph that needs a full face (a completed subset, shaped Arabic, a loaded font) therefore added another set of font objects to the page on every apply, even when the text was the same. The program itself was only shared when it was among the first 8192 objects of the document, so on larger files each edit also copied the whole font program, often several megabytes. `embed_mapping` now looks at the page's own `PCFull` resources first: - one with the same font name, program, glyph map (`CIDToGIDMap` or the CFF encoding CMap) and ToUnicode map is returned as it is, and nothing is written; - otherwise a program one of them already uses is shared, wherever it sits in the document, before the document-wide search. Programs are compared by the length they were written with before their data is decoded, and streams are compared decoded, so a file another writer compressed since is still recognised. Pruning resources a rewrite no longer uses is left for later: a page's /Resources can be shared with other pages, so it needs a check of every content stream that uses it. The test embeds after 9000 other objects, so the program lies beyond the document-wide search. Embedding the same text twice returns the same resource; two mappings share one program; after the streams are compressed, embedding again writes no objects; a different program under the same name gets its own resource. It fails without this change ("PCFull1" against "PCFull0"). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>A relative path that doesn't exist below the root was refused with the path as typed and the system's localised message, so a script written for another working directory ("sub/a.pdf" with --root sub) gave nothing to correct from. The refusal now names the resolved path and the root; paths outside the root keep their uniform refusal. Claude-Session: https://claude.ai/code/session_01RUNQSPVXx3dDBabRZHAnjz Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>Flattening the fields of a laid-out XFA form used to leave the XFA in the file: Adobe's viewers then laid the form out again from the template over the baked pages, so the "flattened" PDF was still a live form there and a plain one everywhere else. pdfcraft_xfa::strip takes the XFA out of a document: the packets (template, data and all), /NeedsRendering on the catalog and the AcroForm, the layout mark, the overrides, and the private keys on every field down the tree. The engine calls it after Flatten form fields on a document with XFA packets, so the result is a plain PDF every viewer shows the same, and for the new Edit::XfaToStatic ("Convert to a static form"; tool xfa_to_static), which keeps the laid-out pages and the fields with their values as an ordinary AcroForm that no viewer lays out again and whose scripts no longer run. Both undoable: the engine's post-edit refresh re-reads the layout mark to drop or restore its XFA state and the cached template. What the packets held beyond the fields is reported (packets by name, data no field showed, buttons left inert, the layout's own warnings, Reader usage rights) as document warnings, and a dynamic form that was never laid out is refused rather than left with nothing. Applying redactions shares the same strip. Closes the last planned XFA parity entry (form.xfa-flatten shipped).* M9: signature labels follow the interface language, and one the font can't draw is refused, never written as ? The labels of a visible signature ("Digitally signed by", "Reason: ", ...) were written in WinAnsi unchecked, and every caller passed the English defaults. Now: - sign: a drawn label is checked as the details are, and one Helvetica can't draw is refused (SignError::Unsupported) naming the label and the character. AppearanceLabels::fields and ::first_undrawable say which labels a caller can use. - ui-egui: signing stamps the labels in the interface language when Helvetica can draw all of them, otherwise all in English (never a mix) with a note under the preview. The preview uses the same labels, the stamp's line layout and the signing time. - automation: sign_document takes optional labels and appearance; a label the font can't draw, an unknown key or one without a visible signature is InvalidArgs. - Catalogs: the five labels and the note in every language; refresh hashes. Follows up the note on #1112. * Refresh catalog hashes after merging main --------- Co-authored-by: Brandon Thomas <echelon@gmail.com>calculate_js wrote a field's simplified field notation as "/** BVCALC expr EVCALC **/ event.value = AFMakeNumber(0);". PdfCraft reads the comment, but a viewer that runs the script instead (Acrobat among them) computed 0. notation_js now writes Acrobat's own translation after the comment: each field name becomes AFMakeNumber(this.getField("name").value), with \ escapes in names honoured, numbers and operators kept. Co-authored-by: Osvaldo Duran <338149330+regendorf-ux@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>* Edit: crop an existing page image with its handles ImageChange::Crop(rect) keeps the part of a page image inside rect (user space) with a clipping path placed just inside the scope that holds the image (or a new q … Q around its Do); a clipping path already at the scope's start, the picture's earlier crop, is replaced, so a crop can grow back. The pixels are never scaled, and a later move or resize wraps the scope, so the crop moves with the picture. ImageEdit::Crop (undo label "Crop image"), image_edit action crop. In the window, right-click ▸ Crop Image puts the selected picture in crop mode: eight handles trim (the inside pans), the part that goes is dimmed, Enter or Done applies, Esc or Cancel leaves; Remove Crop shows the whole picture again. Rows in every language, their checksums in ATTRIBUTION.toml, parity edit.image-crop shipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Image crop: Bulgarian hint without a character the monospace UI font lacks JetBrains Mono has no 'ѝ', so primary_ui_fonts_cover_latin_and_cyrillic_catalogs failed; the hint is reworded ("with its handles" -> "with the handles"). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refresh catalog hashes after merging main --------- Co-authored-by: Osvaldo Duran <338149330+regendorf-ux@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>* M4: set page transitions and display times (/Trans, /Dur) through the engine and the tools organize::set_transition writes or removes a page's /Trans dictionary (only the entries the style reads and that differ from the defaults) and /Dur, with every value checked before any page changes; Edit::SetTransition is one undo step ("Set page transitions", translated in every catalogue); page_transition_set is the tool. The counterpart of reading them (#2074); playing them and the Organize dialog stay planned. Refs #379. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RUNQSPVXx3dDBabRZHAnjz * Refresh catalog hashes after merging main --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>* M14: Italian catalog: complete the missing entries it.tsv lacked 265 keys that the other catalogs carry. The 201 the code looks up are added in one dated section at the end of the catalog: the sentences the accessibility checker, preflight, signature validation and page-range parser word (their WORDINGS), the certificate rows and calendar weekday and month labels (their tl_ctx contexts), digital-ID, docking and print messages, and five plurals (one|other). Italian now has 2,528 entries. The new rows follow the wording the catalog already uses: history labels say "Modifica ..." like "Change {key}", and the Creator and Producer keys that label fills in say "Applicazione" and "Produttore PDF", as the Document Properties dialog names those fields. The Optimize PDF summary says "eliminato" like its Discard options, the checker and preflight sentences say "ha rilevato" and "Viene usato", the trust messages say "nel tuo elenco di certificati attendibili", the password and certificate rows say "non corrispondono" and "rilasciato" like the existing "The passwords don't match." and "Issued by" rows, and the print hint quotes the "Disattivato" option as the dialog shows it. The other 64 are left out because no non-test code looks them up: - 10 tooltip texts with a fixed macOS shortcut ("Zoom in (⌘+)"); the code fills the shortcut in through "{key}" rows Italian already has; - 9 older wordings the code no longer uses: the five Combine folder messages, "Save (M4)", " on page {label}", the owner-only security message and the old "Text recognition isn't installed" message (the code now says "its model files are missing"); - 45 generic labels and plurals only the Lithuanian catalog has. The code says "{n} file|{n} files" as two plain strings, "1 file" and "{n} files", which Italian has; "{n} comment|..." and "{n} result|..." are used nowhere. The entries are AI-assisted translations written from the meaning of the English (clean-room; no proprietary localisation consulted), and keep their placeholders and trailing ellipsis. The catalog's SHA-256 in ATTRIBUTION.toml is updated by hand, as the other catalog changes do. localization-parity.md, the ROADMAP progress log, the M14 rows of docs/roadmap.md and docs/localization.md record the new count, and parity/acrobat-features.toml now says Italian translates the engine's sentences too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refresh catalog hashes after merging main --------- Co-authored-by: kcobelli-pixel <257471167+kcobelli-pixel@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>