Commit Graph

99 Commits

Author SHA1 Message Date
Brandon Thomas 28108ec555 Export detected tables to office formats 2026-10-06 07:38:17 -04:00
Brandon Thomas ea2ed3d911 Forms: say so when a document is an XFA form (#60)
XFA forms aren't read yet, and opening one gave no hint: a dynamic XFA form
showed only its "Please wait…" placeholder page, and a static one looked like
an ordinary form though Acrobat shows its XFA data in preference to the
fields that get filled.

- render: DocInfo.xfa (Static / Dynamic) from /AcroForm /XFA; dynamic when
  /NeedsRendering is true or there are no fields. Exported for doc_info
  (automation and CLI) as "xfa".
- ui: the notice bar explains each case (above the form-fields notice); a
  static form keeps its Highlight fields button.
- Tests: tests/xfa.rs (dynamic with and without /NeedsRendering, static,
  ordinary forms, a malformed /XFA). Parity notes for form.xfa-static and
  form.xfa-dynamic (still planned: this explains XFA, it doesn't support it).

Reported by @Sudachi-dev.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 07:22:33 -04:00
Brandon Thomas 93221c6886 M7: move and resize existing text boxes in Edit text (#40)
In Edit a PDF ▸ Edit text, dragging a paragraph's box moves it, and dragging
the handle on its right edge rewraps it to a new width; a click still opens
it for typing.

- edit: BlockStyle gains offset (user space) and width. rewrite_block puts the
  move inside the paragraph's own q … Q as a cm, taken back through the CTM's
  linear part so a page-space drag lands right in scaled/rotated content
  (the CTM is now recorded at each line's origin). Non-finite numbers are
  refused; widths are clamped to one character .. 14 400 pt.
- ui: BlockDrag on DocView; the box follows the pointer (or its right edge
  does) and the release applies one undoable Edit text step. The width handle
  shows on upright pages only (on a quarter-turned page the screen's
  horizontal is the text's vertical).
- automation: text_edit takes dx, dy and width.
- Tests: engine (move, move under a scaling cm, narrower/wider rewrap,
  non-finite and zero inputs), kittest pointer drags, automation tool.
  Parity: new edit.text-move-resize (shipped).

Requested by @TCB13.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 07:19:53 -04:00
Brandon Thomas b315eff24d Preferences ▸ Identity: the name on new comments, remembered
Comments were signed with the login name (or set_option author), with no way
to change it in the app. Preferences gains an Identity section whose name
field (labelled for screen readers) sets the author of new comments; it is
saved with the settings and restored (an empty name keeps the login-name
default; restored names are capped at 200 characters). Japanese labels
added. Test: identity.rs. Parity comment.author-identity: shipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 19:31:23 -04:00
Brandon Thomas b4e1d488de Comments: an opacity control in the quick bar (per tool, 10-100 %)
The comment tools' quick bar had colour and line thickness but no opacity,
though comments already carry it (/CA) and the Properties dialog edits it.
An Opacity slider joins them for every tool; set_opacity clamps to 10-100 %
so a comment can't be made invisible. Test: a strikeout made at 50 % carries
/CA 0.5. Parity comment.properties-bar: shipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 19:12:24 -04:00
Brandon Thomas c02e1e91c2 Comments: Squiggly underline tool (Highlight flyout, All tools, command)
The engine and agent tool already made squiggly underlines; the UI had no
way to. CommentTool::Squiggly joins Underline and Strikethrough in the
Highlight flyout and the Comment tool's Markup section, as the
comment.squiggly command, and existing squiggly comments edit as themselves.
Test: comments.rs::the_squiggly_tool_marks_selected_text. Parity
comment.squiggly: shipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 18:57:28 -04:00
Brandon Thomas ead70695c8 Tests: dropping a PDF on the window, and hovering a comment (two features now shipped)
Both features worked but had no test, so parity listed them as partial:
- core.drag-drop-open: a file dropped on the window opens in a tab
  (ui.rs::dropping_a_pdf_on_the_window_opens_it, through egui's DroppedFile).
- view.annotation-hover: hovering a comment shows a popup with its author and
  text (comments.rs::hovering_a_comment_shows_its_author_and_text).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 18:29:38 -04:00
Brandon Thomas 7b85af8785 Tests: full screen and the About dialog get their own tests (parity evidence)
Both were marked shipped on the generic 'every registered command is
implemented' test, which the honest assessment flagged. Full screen: the
shortcut enters, Escape leaves, and the command toggles both ways. About:
the dialog shows the running version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 17:30:22 -04:00
midasdf c9d6d39071
Add persisted English/Japanese interface language (#47)
* i18n: add persisted English and Japanese interface language

* ROADMAP: the language entry goes at the top of the log, dated

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

---------

Co-authored-by: midasdf <205497066+midasdf@users.noreply.github.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 17:10:09 -04:00
Justin John e59c9a793e
Fix text editing layout and preserve source PDF font styles (#36)
* Comments: a text box's rectangle follows its edited text

Editing a text box (or typewriter or callout) rewrote /Contents but
kept the old /Rect: the appearance clipped the new text to the old box
and silently dropped lines that no longer fit, while shorter text left
an oversized box. set_contents now re-measures the text with the same
Helvetica widths as at creation and re-fits the box: the wrap width and
top edge stay, the height fits the wrapped lines. A callout's leader
line keeps its place and re-attaches to the moved box (that geometry
moved from set_rect into a shared apply_text_box). A locked box keeps
its text editable, so it re-fits too.

Covered by annot tests (grow and shrink with nothing clipped, callout
leader re-attach, locked box) and a comment_edit round trip through the
automation tools; parity entries cite them.

Co-Authored-By: GLM <noreply@z.ai>

* Polish edit text and images tool

* feat(edit-text): select source font style

* fix(edit-text): preserve detected PDF font styles

* feat(edit-text): support Japanese replacements

* fix(forms): escape non-ASCII format script strings

* Forms: unwrap_or instead of map_or with identity (clippy map_or_identity)

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

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: GLM <noreply@z.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 07:48:23 -04:00
Brandon Thomas de9b9e82bc Updates: check only when asked (no check at start)
By the owner's decision there is no update check at start and no in-place
install for the foreseeable future. The startup option, its setting and the
first-frame trigger are gone; Help ▸ Check for updates is the only request.
Settings written by a build that had the option are ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 06:07:11 -04:00
Brandon Thomas 85a8652de1 Issue #28: Help ▸ Check for updates, with an opt-in check at start
PrintCraft asks GitHub for the latest release and, when it is newer, offers
its release page to download from. Nothing is downloaded or installed
automatically (installing in place needs signed release artifacts).

- ui-egui: updates module (version comparison, background check, dialog);
  no network code: the desktop app supplies the source, and without one
  (web build, tests) the command opens the releases page.
- desktop: one HTTPS request (ureq over rustls with the OS's trusted roots,
  10 s timeout, 1 MiB cap). Only a page under the releases list is offered.
  No bundled root list: webpki-roots/webpki-root-certs are CDLA-licensed.
- The check at start is opt-in and silent unless there is a newer version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 01:40:27 -04:00
Brandon Thomas 70280a44d0 M10: Export to Word (.docx), HTML and RTF (new export crate with a small zip writer): paragraphs, headings, bold/italic, images, page breaks; doc_export_office tool
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 09:40:46 -04:00
Brandon Thomas 4d60af8b1e M11: PDF/A (new preflight crate): verify PDF/A-2b/3b structural rules, Save as PDF/A (XMP identification, generated sRGB output intent, forbidden actions, annotation flags, interpolation, encryption), PDF/A dialog; pdfa_verify, pdfa_convert tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 07:19:54 -04:00
Brandon Thomas 632a21bfcf M13: Action Wizard: built-in actions (Prepare for Distribution, Optimize Scanned Documents, page numbers, confidential, sanitize), custom actions with 12 step kinds, background runs over files; action_list, action_run tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 05:48:19 -04:00
Brandon Thomas a4bf717c06 M12: Compare files: visual differences (pages rendered and compared region by region), shaded orange; doc_compare visual option
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 05:37:23 -04:00
Brandon Thomas c12b795ce5 M12: Compare files (new compare crate): word-level text differences, Compare panel with shading on the new file, report PDF, differences as comments; doc_compare, doc_compare_report, doc_compare_mark tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 05:31:18 -04:00
Brandon Thomas aa194686f1 M6: Prepare a form detects fields (underscore blanks, rules, boxes, check squares) and names them from their labels; form.detect, form_detect_fields
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 05:21:01 -04:00
Brandon Thomas 620ef4fcad M6: Field Properties ▸ Actions tab (six triggers, JavaScript/link/reset/menu/page/show-hide/submit actions); form_actions, form_set_actions tools; signing UI tests get their own temp folders
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 05:08:28 -04:00
Brandon Thomas 6ff0bf8f64 M6: Merge data files into spreadsheet (FDF, XFDF, filled PDF forms → CSV); form_merge_data tool
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:52:59 -04:00
Brandon Thomas 06f8d73ec7 M6: Acrobat JavaScript: sandboxed boa engine with the forms object model (printcraft-js); custom keystroke/validate/calculate/format scripts, button scripts, document JavaScripts, JavaScript console (⌘J), Preferences ▸ Enable JavaScript; js_run, js_document_scripts, js_set_document_script, form_set_script, js_enabled tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:41:47 -04:00
Brandon Thomas a7ffee01b5 M10: Recognize text in multiple files (ocr.recognize_batch, ocr_recognize_files): searchable copies written to a folder in the background
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:54:11 -04:00
Brandon Thomas b87cf39168 M10: Scan & OCR ▸ Recognize text: ocrs-based recognition (models fetched by cargo xtask models), invisible searchable text layer, Recognize Text dialog with background progress; ocr_recognize / ocr_status tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:47:58 -04:00
Brandon Thomas d7c22d7ef0 M7: Justify, underline, line spacing, character spacing and horizontal scale for existing paragraphs (and justify for added text); Lucide align-justify icon
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:16:03 -04:00
Brandon Thomas 385313e0bf M7: Format existing text: font family, bold/italic, size, colour and alignment for a paragraph (Format text panel live while editing; text_edit formatting arguments); centred and right-aligned paragraphs are detected
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:07:43 -04:00
Brandon Thomas c2f53d5595 M7: Edit text & images: select existing page images to move, resize, rotate, flip, replace, save or delete; page_images, image_edit, image_save tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 02:55:08 -04:00
Brandon Thomas 695e460bbb M7: Edit text works on paragraphs: detection, in-place editing with rewrap to the box, original spacing, colour and font (or Helvetica); text_paragraphs and text_edit paragraph
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 02:42:18 -04:00
Brandon Thomas fb6208b089 M7: Edit text: click a line of existing text and retype it in place, reusing its font when it can show the text, else Helvetica; text_lines / text_edit tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 02:25:06 -04:00
Brandon Thomas 01d0dc67ba M5: Fill & Sign typed signatures and initials (Type or Draw; script-font outlines drawn as filled paths); fill_sign_add signature/initials
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:59:28 -04:00
Brandon Thomas 03fca33d10 M5: Text boxes write rich text (/RC XHTML and /DS) in step with their text and style
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 08:11:12 -04:00
Brandon Thomas 9372b25d0b M10: Create PDF from JPEG 2000 images (JP2 or codestream, embedded as JPXDecode); M1: looping /Prev chains test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 08:07:53 -04:00
Brandon Thomas 80a8087ebc M9: Certificate Viewer (chain, Summary, Details, Trust; export, trust) from the Signatures panel; dialog button rows no longer stretch dialogs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 08:00:56 -04:00
Brandon Thomas f58570699e M9: Sign with macOS Keychain identities (keys stay in the Keychain): listed in Sign with a Digital ID; sign_keychain_ids, sign_document id keychain:…
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 07:55:07 -04:00
Brandon Thomas 294cbd6716 M8: Applying redactions cleans the tags: elements of changed marked content lose Alt/ActualText/E, empty marked content leaves them
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 07:48:43 -04:00
Brandon Thomas 1d8b1ecb02 M1/M4: Hybrid-reference files: /XRefStm entries replace the table's free entries; signed documents refuse edits that would force a full rewrite
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 07:45:20 -04:00
Brandon Thomas ba4a7a6d42 M11: Optimizer Clean Up removes invalid links and bookmark destinations and unreferenced named destinations
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 07:40:51 -04:00
Brandon Thomas 763cd70ece M11: PDF Optimizer ▸ Audit space usage: bytes and share of the file per kind of content; doc_audit_space
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 07:37:48 -04:00
Brandon Thomas 55275cd935 M3: Advanced Search panel (⇧⌘F): every match with its context, by page; click to go; shares the find bar's search
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 05:40:22 -04:00
Brandon Thomas e9322b597b M12: Add alternate text: figures one by one with a preview, alternate text or Decorative (content becomes an artifact); accessibility_figures / accessibility_set_alt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 05:36:39 -04:00
Brandon Thomas e8bc0db811 M5: Custom stamps: create from a PDF page or an image under a category and name, kept in the stamp library, placed at natural size; stamp_custom tool
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 05:24:28 -04:00
Brandon Thomas d5c659812c M6: Image fields: Prepare a form ▸ Image field places an icon-only button that asks for a picture when clicked (buttonImportIcon recognised natively); form_set_image
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 05:16:42 -04:00
Brandon Thomas 8486a35207 M4: Combine files lists the files first: reorder, remove, add more, and choose each file's pages (doc_combine pages)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 05:11:25 -04:00
Brandon Thomas 0b628d5515 M12: Accessibility Checker: new a11y crate with Acrobat's 32 rules in 7 categories, HTML report, fixes (language, title, tab order); options dialog and results panel (Fix, Skip Rule, Explain, Check Again, Show Report); accessibility_check / _report / _fix tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 05:05:56 -04:00
Brandon Thomas 1e69a92c41 M10: Export a PDF ▸ Export all images: JPEGs unchanged, other images as PNG with alpha; skipped images reported; doc_export_all_images
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:47:45 -04:00
Brandon Thomas f1817459f2 M10: MCP resources for open documents: information, text, page text and page images (resources/list, templates, read)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:42:21 -04:00
Brandon Thomas 19b5b1d6d2 M1: List document revisions and open an earlier one (Document Properties ▸ Advanced; doc_revisions, doc_open_revision); PDF version reads 1.7, not 17
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:40:25 -04:00
Brandon Thomas 6a9dd32ef9 M3: Tabs and the window title show the document title when Initial View asks for it (DisplayDocTitle); parity for setting the document language
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:34:26 -04:00
Brandon Thomas d26821fdcd M3: View ▸ Zoom ▸ Fit visible (⌘3): zoom so the current page's visible content spans the window
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:32:03 -04:00
Brandon Thomas c0f9c73ae9 M6: Prepare a form ▸ Preview (fill the form as a reader would; Edit fields goes back) and Field Properties ▸ Locked (annotation Locked flag; properties greyed out until unlocked, values still fillable); form_set_props takes locked
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:28:19 -04:00
Brandon Thomas 4df7a73a1a M6: Several fields at once in Prepare a form: Shift/⌘-click to select, then right-click to Align (left, right, top, bottom, centres), Distribute evenly, or Set Fields to Same Size, anchored on the right-clicked field; one undo step each. Test fix: the area-highlight test waits for the text layer before dragging over text
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:23:22 -04:00