Commit Graph
4058 Commits
Author SHA1 Message Date
jonathanwxh-cell 522653d6b1 fix(organize,print): join /Contents array pieces with a space (#3502) 2026-10-25 12:03:40 +08:00
aiongg 418ac6a2af fix(ui): the page ignores the pointer while a panel is being dragged (#4581) 2026-10-24 22:12:46 -04:00
Claude 4c09747773 M4: bookmarks from text styles need copying permission and keep columns apart (#1693)
CodeRabbit on #4560:
- The bookmark titles are the document's text, so the edit now needs
  copying permission as well as assembly, and Document::text_styles (the
  dialog's samples) is empty when copying is withheld; the automation
  text_styles tool already checked it.
- A heading went on to the next row whenever it was close below in the
  same style, so same-style headings in two columns on staggered rows ran
  together into one bookmark. A line continues a heading only when it lies
  under it.
- Lines found their style by a scan over every style so far; they are now
  indexed by font, weight, slant and quarter-point size, so a page with
  thousands of styles no longer makes the scan quadratic.

Regression tests for the first two (each fails without its fix).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LymhVaGZCWwB9HNEbLzeMM
2026-10-25 01:14:19 +00:00
jonathanwxh-cell 24edde6563 forms: clear typed XFA password field values from datasets on save (#3944) (#4506) 2026-10-24 21:08:21 -04:00
Dylan M. Taylor aa9a9105fc fix(redact): remove AcroForm on Hidden::FormFields even when field count is zero (#4571)
* fix(redact): remove AcroForm on Hidden::FormFields even when field count is zero

* fix(redact): report AcroForm presence in scan() and format
2026-10-24 21:07:16 -04:00
Dylan M. Taylor 4c69b8cf88 fix(forms): align has_password_flag traversal depth with field enumeration (#4570)
* fix(forms): align has_password_flag traversal depth with field enumeration

* fix(forms): extend field_chain depth to 64 and fix test formatting
2026-10-24 21:07:09 -04:00
Dylan M. Taylor f4f91d0d5c fix(xfa): require full save when stripping XFA packets (#4568) 2026-10-24 21:03:25 -04:00
RiceDee 08ec1db79b Merge main into fix/undo-in-open-text-editor
Main took integration batch 6 (#4566). Conflict in edit_text_ui.rs: the
overlay keeps this PR's view_id and main's switch to interact_pos for
clicks outside the document.
2026-10-25 11:36:47 +11:00
aiongg c28d1c8e22 Merge pull request #4566 from aiongg/r4-batch
Integration batch 6: 6 contributor PRs (All tools view, page pointer, comments, redaction, Properties, Home)
2026-10-24 20:24:05 -04:00
aiongg 0140f1047c Integration: the page input guard also catches egui's per-button pointer reads (#2685) 2026-10-24 23:56:44 +00:00
aiongg c276f92b54 Integration: the roadmap entry for comment threads says what the count counts (#4061) 2026-10-24 23:55:17 +00:00
aiongg 756660f6d2 Integration: the arrow keys leave a reply to an unnamed comment where it is (#4061) 2026-10-24 23:55:10 +00:00
aiongg 80d8c60ac2 Integration: no link or comment tip beside the open palette (#2685) 2026-10-24 23:23:47 +00:00
aiongg bb06649527 Integration: two comments whose /IRTs point at each other stay comments of their own (#4061) 2026-10-24 23:23:47 +00:00
aiongg e0c319d273 Integration: a comment listed through a reference chain keeps its replies after an edit (#4061) 2026-10-24 23:18:59 +00:00
Lcoding15 4ce68f517b M4: New bookmarks from text styles, for headings that aren't tagged (#1693)
Bookmark options > New bookmarks from text styles... lists the styles the
document's text is set in (font without its subset tag, the size shown,
bold, italic, how many lines, a sample), the largest first, and takes one
style per bookmark level. Every line in a level's style becomes a
bookmark of that level under a new first "Untitled" bookmark, as from
structure; a heading set on several rows is one bookmark, and each goes
to the top of its heading.

The detection lives in engine::text_style_bookmarks on top of
edit::text_lines, reading each page top to bottom then left to right, so
two headings on one row stay two. text_styles and
bookmark_from_text_styles reach it headlessly, and the command
bookmark.from_text_styles opens the dialog. OutlineEntry gets an
optional top for the /XYZ destination; structure bookmarks keep theirs.
2026-10-25 01:03:08 +02:00
aiongg 73240d978f Integration: M3: All tools expands to a full, searchable view (#2460) 2026-10-24 22:48:11 +00:00
aiongg e5005f062a Integration: fix(ui): one page pointer per frame, so taps work and nothing over a page lets it through (#2685) 2026-10-24 22:48:11 +00:00
aiongg d821f91001 Integration: fix(comments): thread replies by their /IRT reference, count comments like Acrobat (#4061) 2026-10-24 22:48:11 +00:00
aiongg f94b34adc9 Integration: fix(redact,cos): cleared redaction marks leave nothing behind (#4226) 2026-10-24 22:48:11 +00:00
aiongg 78dbea442e Integration: M3: the community card on Home can be closed for the rest of the run (#2617) 2026-10-24 22:34:42 +00:00
aiongg 808fe853d6 Integration: fix(ui): Document Properties layout, Space Audit tab, no page cursors under dialogs (#2556) 2026-10-24 22:34:42 +00:00
RiceDee dd47c4f9e1 test(ui): the two-tab Redo test checks the copy's paragraph stays open
If the copy's editor had closed before or during Redo, the check for the
other tab's typing passed on an empty text. It now requires the editor
to be open before Redo and after it.
2026-10-25 08:56:55 +11:00
RiceDee f3b61b73b0 style: rustfmt the two TextDraft test literals that took typing_from 2026-10-25 08:41:17 +11:00
RiceDee dd6e86b6cb Merge pull request #1 from aiongg/fix-4179-main
Merge main; set typing_from in two tests from #4441
2026-10-25 08:37:19 +11:00
RiceDee b9035271b0 fix(ui): menu Undo takes back typing in the open text box first
Edit ▸ Undo with typing in a paragraph or added text box that the page
doesn't have yet applied the typing (a new edit, which dropped the
document's waiting Redo), closed the box and undid the typing all at
once; the key takes it back a step at a time in the box. Menu Undo now
goes to the box first, as Redo does, and is enabled while the box holds
such typing. Undo and Redo share typing_step for the box's own history.
2026-10-25 08:36:17 +11:00
alehelandClaude Opus 5.5 120de553ab fix(ui): the Background preview follows the Replace checkbox
The dialog previews a colour as a tint of the page's thumbnail (main's #3009). It tinted every
page, so with Replace unticked a page that keeps its own white backdrop previewed coloured,
though OK leaves it white. A page a picture covers (a scan) previewed coloured too.

background_tint() now shows no colour where the page will still hide the background after OK:
a scan, or a white backdrop with Replace unticked. It reads the page from the dialog's backdrop
check (BackdropCheck::found, for the current version of the document only); a page the check
hasn't reached yet previews coloured, as before.

Tests, both seen failing with the fix reverted:
- marks_ui::tests::the_preview_shows_a_background_only_where_ok_lets_it_show (the rule);
- it::marks::the_background_preview_follows_the_replace_checkbox (what the dialog paints, per
  page, ticked and unticked).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 23:06:34 +02:00
aiongg ac868f6e29 Tests: new text box drafts set typing_from (main's #4441 tests) 2026-10-24 18:58:44 +00:00
aiongg 43708cf5dd Merge remote-tracking branch 'pr/4179' into lead-check-4179 2026-10-24 18:42:33 +00:00
alehel ad8c2f46dd Merge origin/main into fix/comment-threads-by-irt
Conflicts:
- crates/render/src/inspect.rs: this branch's reply-linking methods and main's NoRotate
  rectangles (#3016) both go in the Annotation impl; the annotation reader takes this
  branch's loop with main's no_rotate field.
- crates/automation/src/comments.rs: this branch's HashMap import, main's import list.
- ATTRIBUTION.toml: each catalogue's source note keeps main's secured-document clause and
  this branch's reply-count clause; ATTRIBUTION.md regenerated (cargo xtask assets --write).
- The 33 catalogues: main's new rows, then this branch's reply-count row.

main's #3016 tests build Annotation field by field; they now set parent and grouped.
2026-10-24 20:42:11 +02:00
alehel 4283936293 Merge origin/main into fix/document-properties-layout
Conflicts: optimize_ui.rs imports (this branch's RichText, main's Compatibility; both kept)
and the organize.document-properties parity entry: both evidence lists kept, main's XMP note
kept, and the tab list now names main's Custom tab (#4387) instead of saying there is none.
2026-10-24 20:37:55 +02:00
aiongg a7801dc84e fix(ui): text typed into a new text box counts as unsaved work (#4441)
* fix(ui): text typed into a new text box counts as unsaved work

Closing a tab or quitting while the only unsaved thing was text in a new Add text box skipped the save prompt and lost the text. The box now counts like fill text does: only when it holds non-blank text.

* fix(ui): saving on close keeps text typed into a new text box
2026-10-24 14:25:44 -04:00
alehel bd7dc0fe8c Merge remote-tracking branch 'origin/main' into fix/background-hidden-by-page-backdrop 2026-10-24 17:35:17 +02:00
Lcoding15 80f919977b M2: page_render and render_preview report the render warnings next to the PNG (#4340)
The renderer reports when a page's picture is incomplete or approximate
(content cut at the page's safety budget, a colour painted in a fallback
colour), but only `pdfcraft-cli render` showed it. `page_render` and
`render_preview` returned the PNG alone, so a script or MCP client could
not tell that the image was not the whole page.

Both tools now return a JSON part after the PNG when the page has
warnings: `{ "page": 1, "warnings": [...] }`, with the sentences the CLI
prints. Warnings are strings, like every other tool's `warnings`, so
`command_run` can add its own to the same list. A page without warnings
still returns the PNG alone, so existing callers see no change.

The viewer notice the issue also asks for is left for a separate change.
2026-10-24 17:10:23 +02:00
RiceDee 25da4b1894 Merge main into feat/align-selected-lines
Conflict in automation/tests/it/automation.rs: this PR's two aligns
tests and main's editable combo box test (#4451) were added at the same
place; all three are kept.
2026-10-25 02:08:55 +11:00
Brandon ThomasandClaude Opus 5.5 d445410807 Order the render integration-test modules (cargo fmt) (#4486)
#4430's merge with main left mod type3_text_clip before mod tiling_cell_placement,
so main's fmt check failed.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 10:57:58 -04:00
alehelandClaude Opus 5.5 866de03fd8 fix(ui): a dialog covers the pages from the frame it opens
The page pointer has the pointer only where egui has the pages on top, and egui knows what
is drawn over them from the layers it met in the frame before. Dialogs are drawn after the
pages, so on the frame one opens egui has not met its layer yet. For that frame the pages
kept the pointer, and a press that landed then was theirs: a link's tip showed over the
dialog, and a click placed a stamp or followed a link under it. main's page_covered had
kept the link's tip and click off the page while a dialog was open, from a hand-kept list.

PagePointer::read now also takes whether a dialog is open: PdfCraftApp::modal_open, the
list the page press and the edge scroll already check, the Unlock prompt included. With one
open the pages see no pointer and no press, except a drag they already have, which goes on
to its release. The palette is not a dialog and the page beside it keeps its tools, so it
is left to egui's layers, from the frame after it opens.

Tests: tests/it/pointer.rs hovers a link and opens the Unlock prompt (no tip in that
frame), and clicks with the Stamp tool in the frame the prompt opens (no stamp). A
page_pointer unit test hides the pointer and a click under a dialog, and keeps a drag the
pages have until its release. With the fix reverted, all three fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:54:28 +02:00
alehelandClaude Opus 5.5 80e290acd1 fix(ui): a tap on a focused check box or radio button keeps its focus
A click on a check box or radio button focuses it, so Tab, Space and the arrows reach it
(#2223). The page hands the click to the field, and the field overlay toggles the box in
the same frame unless the click landed elsewhere. That check read hover_pos, which is None
on the frame egui reports a tap: egui-winit sends PointerGone with every touch release,
and winit reports Windows pen input as touch. So a finger or pen tap counted as a click
away. The focus closed and the toggle was dropped: a tap left a check box unticked and
unfocused, and a tap on a radio button selected nothing. The check now uses the overlay's
clicked_outside, which reads interact_pos, as the other field editors do.

Tests: touch_tap_ticks_a_check_box runs again. tests/it/editor_taps.rs taps a focused
check box and the other button of a focused radio group, each with a mouse click as the
control. Each checks that the focus stays and the tap toggles, and for the radio group that
the arrows still move within it. With the fix reverted, the three tap tests fail and the
controls pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:54:28 +02:00
alehelandClaude Opus 5.5 9f2e1e3293 fix(ui): a tap on an open field or paragraph editor is not a click away
The form field editors and the Edit text paragraph editor are drawn over the pages,
outside the page pointer, and close on a click away. With a finger, or a pen on
Windows (winit reports it as touch), they closed on taps inside them:
- A tap on a combo box opened its list and closed it in the same frame, so a choice
  could not be picked by touch.
- A tap on a list box row picked it, but the list lost focus, so the arrow keys no
  longer moved the choice.
- A tap on a date field's calendar arrows closed the field.
- With a paragraph open in Edit text, a tap on a Format text control that only
  opens a list, such as Line spacing, applied and closed the paragraph, and the list
  went with it.

Two things were wrong. The combo and list boxes judged the click by hover_pos, and
the paragraph's "outside the document" by latest_pos. Both are None on the frame egui
reports a tap, since egui-winit sends PointerGone with every touch release. They now
read interact_pos, which keeps the tap's position on that frame (egui's own
clicked_elsewhere does the same). And egui 0.36 reports a lost focus for two frames.
The text field editor and the paragraph editor judged their exceptions again on the
second frame, when a tap has no position left and a mouse may have moved on. They now
judge a loss once, on its own frame (edit_text_ui::lost_focus_once, with a flag kept
per editor). A focus taken later in a frame is still seen on the next one, as before.

Tests: tests/it/editor_taps.rs taps with support::input::touch_tap, which sends
the release and PointerGone in one frame as egui-winit does, and pairs each tap with a
mouse click as the control. That click leaves the pointer in the window: kittest's
drop_at sends PointerGone a frame later, which the second-frame judging also turned
into a click away. With the source reverted, the four tap tests fail at their bug
assertion and the controls pass. Reverting one part at a time fails only its own
tests: hover_pos in the combo and list check, egui's lost_focus in the field editor
(the calendar) or in the paragraph editor, and latest_pos for the paragraph's outside.
A tap inside an open text field already worked and has a guard test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:54:28 +02:00
alehelandClaude Opus 5.5 1bda33975d docs: page modules read PagePointer, never egui's raw pointer state
A one-line non-negotiable in CLAUDE.md, next to Layering, so agents and contributors
know the rule before the test tells them: page modules read the pointer through
PagePointer (crates/ui-egui/src/page_pointer.rs), never hover_pos, interact_pos,
latest_pos, press_origin or the button reads. It names the test that enforces it,
page_pointer::tests::page_modules_read_the_pointer_only_through_page_pointer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:54:28 +02:00
alehelandClaude Opus 5.5 3ff8222d72 test(ui): page modules read the pointer only through PagePointer
A plain #[test] in page_pointer.rs reads the source of the page modules (the per-page
chain in canvas::document_area and the modules it calls) and fails on any raw read of
egui's pointer state: hover_pos, interact_pos, latest_pos and press_origin, Context's
pointer_*_pos shortcuts, and the primary_* and any_* button reads. Its message names the
file and line and points to PagePointer. 24 open PRs add such reads to these modules, and
three of them (#2137, #1709, #2235) merge cleanly on top of the snapshot, so they would
quietly bring back the touch and overlay bugs it fixed. CI's existing cargo test
--workspace runs it on Linux and Windows.

To pass, the snapshot also carries the button state (primary_down and any_down, global as
before), and the page-input button reads that were left use it or the frame's press edge:
drag ends in Prepare, redact, the Link tool, added content, Edit text and objects, the
comment grab check, a text field opening on the press, and the press that makes a page
current. Code in these files that is not page input is listed, each with its reason, in
NOT_PAGE_INPUT: the field, paragraph and added-text editors (Areas of their own), the
signature dialog's Scan tab, Organize Pages, the page size hint, comment key handling, and
four view gates in document_area that run before the pages' widget exists (zoom anchor,
drawing edge scroll, glide interruption, full screen's click to turn the page), now small
named functions. Prepare a form's calculation order overlay (calc_order_ui) is a page module
too, and takes the pages' pointer for its hover. The test also fails
on a list entry that reads no pointer state any more, and on a source file that takes
PagePointer without being listed as a page module.

Seen failing: a raw hover_pos() put back into zoom_snap.rs, and main's raw read put back
into the stamp block of document_area, are reported with their lines, as are a stale list
entry and crop.rs left off the module list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:54:28 +02:00
alehelandClaude Opus 5.5 cc4726f6e6 fix(ui): one page pointer per frame, so taps work and nothing over a page lets it through
The page view had no single reading of the pointer. About twenty page modules each
read egui's raw state (hover_pos, latest_pos, interact_pos, press_origin) and tested it
against an unclipped page rectangle. That state knows nothing of what is drawn over the
pages, and hover_pos is None on the frame a finger or a Windows pen lifts: egui-winit
sends PointerGone with every touch release, and winit reports Windows pen input as
touch. So a tap placed no stamp, followed no link and ticked no check box. A touch drag
of a comment never committed, and the next drag anywhere on the page moved the comment.
The Stamp crosshair showed on the command palette, on the quick bar and on the chrome
over a page scrolled under it, a link's tip floated over the Unlock prompt, and a
double-click on a dialog's backdrop selected the word under it.

canvas::document_area now reads one PagePointer per frame from the pages' content
widget (step 1 of the page pointer router in the cursor-handling review):
- pos: interact_pos, which keeps the position through a touch release, only while egui
  has the pages under the pointer with nothing over them (contains_pointer, and the top
  layer there is the pages', as the closed #2626 did) or while the pages hold a press.
- origin: where the held press began, also on the frame that brings both the press and
  its release. This replaces the text layer's raw-event fallback (#2100).
- edges: the frame's primary presses and releases on the pages, in order.

It reaches the page modules through comments::PageCx and as an argument: the stamp
blocks, text layer, page press and link and comment hover in canvas.rs; comments and the
signature drag preview; forms and Prepare a form; Fill & Sign and the Sign area; crop,
marquee zoom, snapshot, camera and measure; redact and the Link tool; added content,
Edit text, images and objects. page_covered, a hand-kept list of what covers the pages
that missed the Unlock prompt, is gone. The pages' hover tip is click-through, as a
tooltip is, so a quick move onto it does not take the pointer off the link under it.

Tests: tests/it/support/input.rs sends pointer input in the frames the platform delivers
it in (a touch tap and drag, a click in one frame, a double-click). kittest otherwise
runs one frame per event, so the suite never saw a touch release. tests/it/pointer.rs
holds the review's probes and #2626's layer tests. With the fix reverted, the
tap (stamp, link, check box), touch drag, palette, quick bar, chrome, Unlock tip and
dialog double-click tests fail, and the mouse-click and one-frame-click controls pass.
The tip test fails with the tip interactable, and each page_pointer unit test fails
under a mutation of the part it pins. The probes for later steps stay ignored: the
link hand and the I-beam over other tools' targets (step 2), paragraph edges (step 3)
and Escape mid-drag (step 4). touch_tap_ticks_a_check_box is ignored until the
check box focus fix that follows: since #2223 a tap on a check box counts as a click away
from its focus.

tests/it/comments.rs: the multiline markup hover test (#3541) hovered a point below the
window on a page rotated 270 degrees, and its tip showed only because the hover was
tested against the page's whole rectangle. Its harness now zooms to 100 %, so every
rotation shows the whole page, and the hover helper asserts the point is on screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:54:28 +02:00
cc5fd54868 M6: an editable combo box takes a typed value (ISO 32000-2 Table 233 Edit) (#4451)
A combo box with the Edit flag (bit 19) opened only its list, so a value
that isn't one of its options could not be typed on the page, although
form_fill already took one. ISO 32000-2 12.7.5.4 and Table 233: with Edit
set, "the combo box shall include an editable text box as well as a
drop-down list".

- An editable combo box now opens a single-line text box over the field
  as well as its list. Enter, Tab or a click away commits the text as
  Edit::SetFieldValue with a Choice, the path form_fill and the list use,
  so undo, field scripts and the appearance follow; a pick from the list
  still sets an option.
- The editor starts on the shown text of the picked option, and typing a
  shown text picks that option (the engine maps it to its export value).
- A combo box without Edit is unchanged: a drop-down list only.
- Tests: kittest typing into an editable combo (Enter, list pick, Tab,
  save, undo) and a non-editable one refusing typing; automation
  form_fill takes free text only with Edit, drawn before and after save.
- Parity: form.fill-choice notes and evidence.


Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-24 10:44:38 -04:00
Perchenko AntonandBrandon Thomas 94a12715ce Remember the annotation tool pin across restarts (#4253) (#4276)
* M14 #4253: remember the annotation tool pin across restarts

* M14 #4253: clarify roadmap timezone and Markdown formatting

* Keep main's roadmap status lines; only the progress-log entry is new

* Take main's forms.rs: main already gives each form test its own folder

* Roadmap: drop the form-test folder note (main already has its own)

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-24 10:44:33 -04:00
alehel c11946763b Merge remote-tracking branch 'origin/main' into fix/background-hidden-by-page-backdrop
# Conflicts:
#	crates/ui-egui/src/commands.rs
#	crates/ui-egui/src/marks_ui.rs
2026-10-24 16:39:04 +02:00
0dd871f772 M2: a Separation /All colour paints every colourant, gray 1 − tint on screen (ISO 32000-2 8.6.6.4) (#4439)
The special colourant name All refers to every colourant of the output
device at once, and on an additive device its subtractive tint is
complemented before it is applied (ISO 32000-2 §8.6.6.4). The vendored
colour code treated All as an ordinary spot colourant and drew it through
its tint transform, so a /DeviceCMYK transform giving cyan drew 0.5 scn
as light cyan instead of a 50% gray.

Vendored hayro-interpret patch 66: Separation::convert_f32 writes the gray
1 − t for each tint of an All space without evaluating the tint transform.
Fills, strokes, images and shadings in that space all convert through it,
and so does the RGB print raster. /None still paints nothing, other names
still use their alternate, and a DeviceN space naming All keeps its
alternate (the clause defines the name for Separation spaces).

Tests: crates/render/tests/it/separation_all.rs (synthetic).


Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-24 10:36:24 -04:00
6718f1f34e M2: Type 3 text in rendering mode 7 is not rendered and adds no clip (ISO 32000-2 9.3.6) (#4430)
ISO 32000-2 9.3.6: for a Type 3 font, modes 3 and 7 shall not be
rendered, the other modes render the glyph descriptions, and modes
4 to 7 add nothing to the clipping path. Vendored hayro-interpret
patch 42 drew every mode but 3 filled, so 7 Tr painted the glyphs
in the fill colour (black by default) wherever a following fill
did not cover them.

Patch 64: show_glyph keeps mode 7 for Type 3 glyphs and reports
them as clipping text (GlyphDrawMode::Clip, painting nothing, kept
by extraction), and clip_glyph's Type 3 arm is a deliberate no-op.
Modes 0-2 and 4-6 still render filled.


Claude-Session: https://claude.ai/code/session_0175FWj4xFhMhSH3UpMU8DSC

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-24 10:34:36 -04:00
9aef0dfb78 refactor(xfa): explicit model imports (Sonar S2208) (#4403)
* refactor(xfa): replace model wildcard imports with explicit names (Sonar S2208)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(xfa): complete explicit model imports

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(xfa): drop unused model imports

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Import Corner, which main's parse.rs now uses

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-24 10:31:05 -04:00
NetterSilverandClaude Haiku 5.5 82f0b6f8a0 Reject non-finite numbers in XFDF coordinate lists on import (#4449)
Found while testing crates/xfdf/src/lib.rs:274-276 (csv) used by annot_from_xml at :924-928

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-24 10:30:38 -04:00
aiongg 5fa865f82a fix(ui): header, footer and watermark previews step through the pages (#4448)
* fix(ui): header, footer and watermark previews step through the pages

The marks dialogs preview the current page, or the first page the range
selects when it leaves the current one out, with no way to look at
another page. Arrows beside the page label step the preview to the
previous or next page the range selects. The page stepped to resets
each time the dialog opens.

* fix(ui): the marks preview forgets a stepped-to page the range leaves out
2026-10-24 10:30:34 -04:00