Commit Graph
4320 Commits
Author SHA1 Message Date
mtlcl410andClaude Opus 5.5 6506c8cc45 M3: a fractional zoom is remembered as it was, not rounded to a whole percent (#1767)
Review follow-up on #2195: the last view stored ViewDefaults::zoom_name(),
which rounds 62.5% to 63%. A fixed zoom is now written with its fraction
(with_zoom already reads it back); the fit tokens are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
2026-10-24 10:09:48 +08:00
mtlcl410andClaude Opus 5.5 fb53ddf02f M3: full screen neither is remembered as the last view nor hides it (#1767)
CodeRabbit on #2195: a file opened while full screen was on entered the presentation
first, and the remembered view then replaced its one fitted page, while leaving full
screen went back to the display from before the restore; and a tab closed (or settings
saved) in full screen remembered full screen's temporary fit and display. The remembered
view is now applied before the presentation starts, and the view remembered is the
normal display (DocView::normal_display: the one presenting replaced) at the page
reached.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:09:47 +08:00
mtlcl410andClaude Opus 5.5 7dc18ee131 M3: the restore-last-view preference in the catalogues added since (#1767)
Catalan, Finnish, Hindi, Indonesian, Korean, Romanian and Albanian have coverage
tests the new preference failed after rebasing onto main; Norwegian Bokmål and Thai
get it too. AI-assisted, marked as not reviewed by a native speaker. Lao and Central
Kurdish fall back to English for now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:09:47 +08:00
mtlcl410andClaude Opus 5.5 5e69e620a3 M12: the last view remembers the two-page cover setting (#1767)
Review follow-up on #2195.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:09:47 +08:00
mtlcl410andClaude Opus 5.5 aa190d98b2 M3: Vietnamese for the restore-last-view preference (#1767)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:09:47 +08:00
mtlcl410andClaude Fable 5.1 946fb31eef M3: restore last view settings when reopening documents (#1767)
A file opened again shows the page, zoom and page display it was last
shown with, as Acrobat's "Restore last view settings when reopening
documents" does: remembered by path (the last 100 files) when its tab
closes or settings are saved with it open, applied over the file's own
initial view, on by default and switched off in Preferences ▸ Documents
and view.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-24 10:09:47 +08:00
Eric Kaden a7d86dea76 M12: a flowed subform's last part keeps its bottom margin inside the content area 2026-10-23 22:05:46 -04:00
Eric Kaden 6d7e887efe M6: a paste into a full field keeps the longest part that fits, across a change of font 2026-10-23 22:04:52 -04:00
NetterSilverandClaude Haiku 5.5 42910de473 Reject open-ended page range on a document with no pages
Found while testing crates/print/src/range.rs:69-76

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 01:56:46 +00:00
Eric Kaden d7da5dfe29 M12: a flowed XFA subform a page break cuts gets a closed border on each page, its margins repeated 2026-10-23 21:54:55 -04:00
mtlcl410andClaude Opus 5.5 d64a698825 fix(parity): cite the booklet print test at its path under tests/it (#2707)
main moved the ui-egui integration tests into tests/it, so xtask parity
could no longer find print.booklet's ui-egui evidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
2026-10-24 09:39:26 +08:00
mtlcl410andClaude Opus 5.5 2f97fd2d59 M5: the placeholder for an unknown stamp name stays grey whatever its /C
An AP-less stamp whose /Name has no drawing got its placeholder frame in
the annotation's /C colour (/C [1 0 0] drew a red frame), while the doc
comment and parity note promise a neutral grey one. The frame now always
strokes PLACEHOLDER_GREY; the fourteen Table 184 names keep /C.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
2026-10-24 09:27:38 +08:00
mtlcl410andClaude Opus 5.5 184e9f30ff M10: a booklet decides two-sided itself, as Acrobat does (#2707)
dialog hides Two-sided while Booklet is chosen and prints the booklet two-sided itself
(Using Acrobat X Pro, Print dialog box options: "Acrobat automatically enables duplex
printing, if available, for booklet printing"; later manuals and the current help no
longer say so, and on a current Acrobat the Two-sided control is shown for Size and
hidden for Booklet with the same duplex-capable printer). print::booklet_duplex gives a
booklet's setting: both sides flip on the short edge, the fold of a 2-up sheet turned
sideways; front or back only is one pass of a manual duplex and prints one-sided. The
Print dialog hides Two-sided while Booklet is chosen and sends that setting, leaving the
Two-sided choice as it was for the other layouts (and as #2001 remembers it); doc_print
applies the same rule. This replaces the first version, which rewrote Two-sided to the
short edge when Booklet was chosen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 09:27:26 +08:00
mtlcl410andClaude Opus 5.5 3db28cc4e3 M5: stamps without an appearance draw the stamp they name (ISO 32000-2 Table 184)
A rubber stamp from another program with no normal appearance was not
drawn at all. The display copy now gives it one:

- the fourteen standard names of Table 184 draw that stamp with
  PdfCraft's stamp drawing (eight from the palette, six with labels of
  their own), fitted to /Rect, in /C or the stamp's colour;
- no /Name draws Draft, the table's default, unless /IT says the stamp
  is an image or a snapshot;
- any other name (names match byte for byte, §7.3.5) draws a thin grey
  frame with both diagonals, so the stamp stays visible and selectable.

The drawing is display-only, like the other comments without an
appearance: Save writes the file as it was, and build() still declines
these stamps, so restyling and flattening never write it into the file.
A stamp with its own /AP /N is never touched. stamp() now takes the
label and the sign-here flag instead of a StampKind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
2026-10-24 09:15:12 +08:00
mtlcl410andClaude Opus 5.5 b12965ea8e M6: the date picker has a Today button (#4274)
The calendar under a date field had no way to pick today: from another
month the only way back was the arrows. A Today button now sits under
the days, centred under the grid. It picks today from whichever month
the calendar shows, exactly as a click on today's cell would: written
with the field's own format through format_date, then the same commit
path, so the field's scripts treat it as they treat a clicked day, the
pick is one undoable edit, and the field and its calendar close. A year the field's date can't hold offers
no button. Hovering it shows the full date. One UI string in all 33
catalogues, marked AI-assisted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC
2026-10-24 07:39:44 +08:00
Eric Kaden f5e74991ed M12: flowed XFA subforms are drawn with their border and fill 2026-10-23 19:30:43 -04:00
Eric Kaden 64bdea4e61 M6: fields that don't scroll stop taking text when full 2026-10-23 19:25:32 -04:00
nlevaandOpus 5.5 medium ultracode 5515f321c8 M7: copy added JPEG 2000 images as their file (#2636)
Review: copying an added JPEG 2000 image failed even within its own
document, because the exporter can't write JPEG 2000 yet. Add Image stores
such a picture as the file it was given, so that file is the copy: it
pastes into the same document as the same object and into another as one
embedded image. The notes now also say that a CMYK picture stored
losslessly turns to RGB in another document.

Co-Authored-By: Opus 5.5 medium ultracode <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017gEgu9NcTcPqKovsLyfPxK
2026-10-24 01:17:34 +02:00
nlevaandOpus 5.5 medium ultracode 302ad68502 M7: paste added text boxes and images in the engine and through content_copy (#2636)
Edit::PasteContent pastes an added text box or image copied in the same
document or another, as it was (a text box's style; an image's picture,
turns, flips and crop), as one undo step. A pasted image draws its picture
from the copied object while that is still the picture in the target, else
from an added image there that already holds it (an earlier paste from
another document), else the file is embedded. Document::added_image_file
gives a copied image's picture as a file and honours the copy permission.

pdfcraft_edit::added::paste_rect / paste_place place a paste where the item
was, 18 pt down and to the right past each copy of it on the page (an image
with the same box and transforms counts whichever object holds its
picture), or at a point, kept on the page.

The content_copy tool drives it headlessly, across pages and documents.

The desktop keys and menus come in follow-up PRs.

Co-Authored-By: Opus 5.5 medium ultracode <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017gEgu9NcTcPqKovsLyfPxK
2026-10-24 01:17:34 +02:00
Philip 0ad7396cf7 Merge remote-tracking branch 'origin/main' into feat/edit-scanned-page-offers-ocr 2026-10-24 00:02:56 +01:00
Osvaldo Duran MelendezandClaude Opus 5.5 8b2cefc04c Merge upstream main a2ec27b4 into pr/attachments: translation catalogs and notes kept from both sides, ATTRIBUTION hashes recomputed (conflicted: nothing)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 18:16:24 -04:00
alehelandClaude Opus 5.5 3485e92a95 fix(edit): backdrop copies keep no reference that outlives a redaction
The tag on a page's backdrop copy, `/PCBackdrop << /Original ref /At /Len >>`, kept the
page's original content stream reachable. After Add background, then Redact (or Remove
Hidden Information, or Edit text) and a full save, the text taken off the page was still in
the file, in the original stream the tag pointed at. Text extraction didn't show it; reading
the file's bytes did. Restore also gave up after any edit, so the fill stayed off without a
word.

The tag is now `/PCBackdrop << /Index n /Op (f) /Before <SHA-256> /Was [num gen] >>`: how many
of the copy's operators come before the `n`, the fill it stands in for, a hash of those
operators by value (redaction writes the stream out again with other spacing), and the
original's number as two integers, which keep nothing alive.

Remove background turns the fill back on in the copy when the operators before it still
hash the same and a scan with the fill restored finds it painted first, covering the page.
Edits and redactions after the fill are kept. When the original stream is still there with
the same bytes, the page points at it again. Otherwise the copy stays as it is, and
Remove background says which pages keep their own backdrop off: `EditNotice::BackdropsLeftOff`
(engine), a toast in the app, `warnings` from `doc_remove_marks`. `edit_notices` holds
`EditNotice` now, with the undrawn-text notice as one of its kinds. The two new UI strings
are in all 33 catalogues.

`sha2` (already in the lock file) becomes a dependency of `pdfcraft-edit`.

Tests, each seen failing with its piece of the fix reverted:
- `the_tag_holds_no_reference_and_a_full_save_keeps_no_second_copy_of_the_page` and
  `removed_text_leaves_the_file_when_a_background_replaced_the_pages_backdrop` (automation,
  redaction and Remove Hidden Information through a full save): fail with `/Original` back.
- `a_fill_that_would_cover_content_painted_before_it_stays_off`: fails without the re-scan.
- `a_copy_written_out_again_with_other_spacing_still_comes_back` and the automation test:
  fail when the raw bytes are hashed instead of the operators.
- `an_edit_after_the_fill_is_kept_and_the_backdrop_still_comes_back`: fails under the old
  rule (only an unchanged copy comes back).
- `remove_background_names_the_pages_whose_own_backdrop_stays_off` (engine),
  `remove_background_warns_about_pages_whose_own_backdrop_stays_off` (automation),
  `remove_background_says_which_pages_keep_their_own_backdrop_off` (UI): fail without the
  notice.
- `a_change_before_the_fill_leaves_it_off_and_names_the_page`,
  `a_tag_that_does_not_add_up_is_left_alone` (hostile and old-format tags, never a panic),
  `operators_hash_by_value_not_by_spelling`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 23:58:42 +02:00
Kyle Kassen e373dffa20 M8: redact labelled Italian international slash numbers 2026-10-23 16:37:10 -05:00
Kyle Kassen 50b5e90d63 M10: apply soft-mask Decode intervals to image exports 2026-10-23 16:37:10 -05:00
Kyle Kassen 9dc4bd598c M10: preserve table text from covered export slots 2026-10-23 16:37:10 -05:00
Kyle Kassen 1a69e50826 M10: document annotation resource collision regression 2026-10-23 16:37:10 -05:00
Kyle Kassen 30d85bbf15 M10: write DOCX cell widths from their grid columns 2026-10-23 16:37:10 -05:00
Kyle Kassen 12d1956190 M11: keep default GitHub username contributor credit 2026-10-23 16:37:10 -05:00
Kyle Kassen a8839bc5b1 M10: preserve page artwork when printing annotations 2026-10-23 16:37:10 -05:00
Kyle Kassen bf86689fd7 M11: measure optimizer image resolution in physical page units 2026-10-23 16:37:10 -05:00
Eric Kaden 352ebb1477 M12: a backslash ends a web link's host, as web addresses read it 2026-10-23 17:28:22 -04:00
Eric Kaden 3355edad42 M12: only a link's own underline joins its pieces, and web links need a host 2026-10-23 17:19:25 -04:00
Dylan M. Taylor a2ec27b477 ci(sonar): don't cancel superseded runs on main, so coverage is published (#4321) 2026-10-23 17:06:26 -04:00
Eric Kaden 3cf6e5f716 M12: a link's pieces don't join across a rule, picture or field between them 2026-10-23 17:05:18 -04:00
Eric Kaden ac181479ef M12: a round check button's underline border stays an underline 2026-10-23 17:03:53 -04:00
Eric Kaden ba37d412e8 test(ui): recovery idle tests make folders that never share a name 2026-10-23 17:02:14 -04:00
Eric Kaden d91028a990 M12: a link's address is shared by its runs, words and spans, not copied 2026-10-23 16:47:19 -04:00
Lcoding15 a4c5e5f9ee M7: the stand-in note names every standard family it can use (#4280)
CodeRabbit on #4316: the edit.font-reuse-substitution note said Helvetica
stands in for missing glyphs, but the face follows the source font's
family (Helvetica, Times or Courier) and its weight and slant.
2026-10-23 22:46:57 +02:00
Lcoding15 0b3b243e9a M7: a bold paragraph's stand-in font no longer turns earlier edits bold (#4280)
Edit text set a paragraph whose font lacks a typed character (an accent
missing from a subset) in a standard font, always under the resource
name PCEdHelv, whatever face it stood for. Rewriting a bold paragraph
after a regular one replaced PCEdHelv with Times-Bold, so every
paragraph set in the earlier stand-in turned bold, and the editor's
draft measurement saw those paragraphs change and grew its frame over
them.

The stand-in is now named after its face (PCEdTimesBold, ...), as the
line and region rewrites already name theirs.

Fixes #4280
2026-10-23 22:46:56 +02:00
Eric Kaden 21f3241e6d M12: a round border as wide as its check button fills it as a disc 2026-10-23 16:45:40 -04:00
alehel e38b129450 Merge remote-tracking branch 'origin/main' into fix/background-hidden-by-page-backdrop
# Conflicts:
#	ATTRIBUTION.toml
2026-10-23 22:44:29 +02:00
alehel baacdd4dc8 Merge remote-tracking branch 'origin/main' into feat/all-tools-expand-view
# Conflicts:
#	ATTRIBUTION.toml
2026-10-23 22:44:00 +02:00
aiongg c4a6dd6be3 Assets: don't hash translation catalogs in ATTRIBUTION.toml (#4284)
* Assets: translation catalogs aren't hashed

The 33 UI translation catalogs are project files under the project
licence, and git history records their provenance. Their ATTRIBUTION.toml
entries keep title, author, source and licence but carry no sha256, so a
PR that changes UI text no longer has to edit ATTRIBUTION.toml.

cargo xtask assets accepts a kind = "translation" entry for a .tsv under
crates/ui-egui/src/i18n/ without a hash, rejects one that has a hash, and
still requires a hash for every other entry.

* Assets: a leftover hash on a translation catalog is a note, not an error
2026-10-23 16:41:52 -04:00
Eric Kaden 0008a18345 M12: XFA borders and rectangles with rounded corners are drawn rounded 2026-10-23 16:41:22 -04:00
srt8hellcat2-ui 30438bf595 Format the nested batch the way rustfmt wants 2026-10-23 16:23:04 -04:00
Eric Kaden 1c4a481ea3 M12: round XFA check buttons draw a round background and border 2026-10-23 16:19:43 -04:00
Eric Kaden 0b8758eda3 M12: links in XFA rich text become clickable links 2026-10-23 16:16:40 -04:00
alehel 7e469b9961 Merge remote-tracking branch 'origin/main' into feat/all-tools-expand-view
# Conflicts:
#	crates/ui-egui/src/i18n/mod.rs
2026-10-23 22:02:03 +02:00
Guillem Hermida a1f6a64d4a tests: the pending-open control test waits for the worker by time, not by 30 frames 2026-10-23 21:50:24 +02:00
Guillem Hermida 7668a2c378 tests: each forms test saves into a folder of its own
tabbing_back_to_the_same_field_then_saving_keeps_the_committed_value (its
same-frame case) and typing_and_saving_in_the_same_frame_saves_the_last_keystrokes
both asked scratch() for "same-frame". The tests of the it binary share one
process id and run in parallel, so they got the same folder, and one could
clear it while the other was saving into it: the save then failed to read
back with NotFound. scratch() now adds a number taken per call.
2026-10-23 21:50:24 +02:00