Commit Graph
15 Commits
Author SHA1 Message Date
BooksandBrandon Thomas e7a15783f3 Export to Word/HTML/RTF: read text and images drawn by form XObjects (fixes #314) (#406)
* Export to Word/HTML/RTF: read text and images drawn by form XObjects (fixes #314)

The office export built its paragraphs from text_blocks and its images from
page_images. Both read only the page's own content streams (they back Edit
text and Edit image, which rewrite those streams), so a page drawn through
`/Fm1 Do`, as many print-to-PDF tools emit, exported as an empty document.

Add read-only reading_blocks and reading_images to pdfcraft-edit. They
follow Do into form XObjects (nested ones too), apply each form's /Matrix,
use its own /Resources (or the caller's when it has none), and start it
from the graphics state at the Do. Depth is capped at MAX_FORM_DEPTH and a
form already being read is skipped, so self-referencing and mutually
recursive forms are read once. export_pages uses them; editing is
unchanged and still offers only the page's own text and images.

* Export: a page's walk through form XObjects has a total visit budget, so forms that fan out can't hang it

* Export: keep the image walk within clippy's argument limit

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-09 18:22:07 -04:00
8e3782d5ca Flatten Fill & Sign marks when saving (#464)
* M5: flatten Fill & Sign marks when saving

Saving can now bake typed text, marks and signatures into the page, from Preferences or doc_save. The option defaults off, so a normal save still leaves them editable, and other comments and form fields stay.

* M4: zoom the Organize page grid

The page grid draws its pages at 50% to 300%: toolbar buttons with a
percentage that resets to 100%, trackpad pinch or Ctrl/⌘ + wheel about
the page under the pointer, and ⌘+ / ⌘− / ⌘0 (which no longer change the
hidden page view's zoom while the grid shows).

Thumbnails are re-rendered sharper in a few steps as the grid grows,
capped so one document's thumbnails stay within 256 MB. The page under
the pointer (or the first one in view) stays where it is across a zoom.

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

* M4: zoomed grid pages are rendered at the size drawn

A zoomed page grid stretched 132 pt thumbnails, and the stepped detail
that was meant to help was capped by a memory budget, so a long document
stayed blurry at any zoom.

Pages drawn larger than their thumbnails now get a render at exactly the
size drawn while they are in view; the thumbnail stands in until it
arrives. Only pages in view keep one, so memory no longer depends on the
page count, and thumbnails go back to their one fixed size.

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

* View: the middle button pans instead of drawing with markup tools

egui's drag responses accept every pointer button, so on Windows and macOS a
middle-button drag reached the page tools: with Draw (ink) selected it drew a
stroke, and other tools cropped, selected or moved. Linux was unaffected
because its middle-click auto-scroll already blocks page input.

Outside Linux a middle-button drag that starts in the viewport (document or
Organize Pages) now pans 1:1 while the button is held, with a Grabbing
cursor, and page input is blocked from the press through the release. Linux
keeps its latched auto-scroll.

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

* M3: a short page gone to from the Pages panel stays current

The current page was whichever page showed most of itself. Going to a short
page (a cheque) above a tall one scrolls it to the top, where the tall page
below shows more, so the current page and the Pages panel's highlight moved
to the tall page instead of the one clicked. The page navigated to now stays
current while it is wholly on screen.

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

* M4: page operations from the Pages panel: context menu and drag to reorder

Right-clicking a thumbnail offers Extract pages, Cut, Copy and Paste after, on
the selection or on the page clicked (which becomes the selection), as the
organize grid does. Dragging thumbnails moves the selection, or the page
grabbed, to the gap it is dropped on: a bar marks the gap, the page count
follows the pointer, and the panel scrolls near its edges. The move is one
undoable step; the moved pages stay selected and the current page follows
its page. Documents that forbid assembly keep click-only thumbnails.

Parity: view.thumbnail-context-ops is shipped, with what it still lacks.

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

* Pages panel: only the primary button drags thumbnails; a drag left over after the panel closed or the document changed is dropped

* M5: translate Fill & Sign flatten labels into Ukrainian

The coverage test failed because the new preference strings had no Ukrainian entries.

* Fix main CI: move the rotated-field render test out of pdfcraft-forms (#591)

#516 added pdfcraft-render as a dev-dependency of pdfcraft-forms for one
rendering test. Both crates are layer 3, so `cargo xtask layers` (run in
CI) rejects the sideways edge and main went red. The test now lives in
crates/engine/tests/form_rotation.rs, where both crates are already
dependencies, and forms drops the dev-dependency. The parity evidence
points at the new location.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* uk: the author's wording for the flatten setting

---------

Co-authored-by: samehelhawary <basio20044@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Cody Vogt <Cody.Vogt@caltechsurveys.com>
Co-authored-by: William Max & Co. <info@williammax.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-09 14:25:08 -04:00
f1af1e2e79 Issue #125: page text the standard fonts can't draw is refused, not written as ? (#510)
Add text, headers/footers and watermarks wrote every character outside
WinAnsiEncoding as `?` and reported success. They now refuse it with a
specific error ("the standard fonts can't draw "中" (U+4E2D) ...") before
changing anything, as the maintainer asked on #327. Form fields and
text-box comments are unchanged (they keep the value).

- fonts: win_ansi_encodable / first_non_win_ansi, defined through
  win_ansi itself so a fuller table widens them too; the edited-text
  Type 3 decision uses the same check (same character set as before).
- edit: one drawable() check, fed the lines exactly as each tool draws
  them, so a CR that would become `?` is refused and CRLF in headers is not.
- ui: the Add-text editor keeps such text open with an inline warning.
  Done, a click elsewhere or a double-click on another item don't take
  or replace it; it counts as unsaved work; Save stops and shows it; a
  deleted page takes its draft with it.
- Arabic (#403): one public check, first_undrawable, follows the drawing:
  Arabic shaped with the craft-fonts face is drawable, and only what's left
  to the standard font counts. Without the face, #403 still decides for the
  Arabic letters (new items refused with what's missing, existing ones stay
  movable), but nothing else in the item may become `?`. The editor uses
  the same check, cached per draft.
- #403's odd_arabic_text_never_panics: its U+2029/U+0085 input, which was
  drawn as `?`, now expects a refusal naming the character.
- The warning is translated (fr, ru, zh-hans, zh-hant, es, ja, bg, de); the
  catalogs' SHA-256 entries in ATTRIBUTION.toml are updated.


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

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-09 13:20:47 -04:00
Brandon ThomasandClaude Opus 5.5 d3db99818f Rename PrintCraft to PdfCraft (#174)
The app, crates, binaries, bundle id, packaging, icons, screenshots and docs are now
PdfCraft / pdfcraft (repo storytold/pdfcraft). On first launch the desktop app moves the
PrintCraft settings and crash-recovery folders to the new name, and both apps read settings
saved under the old storage key, so upgrades keep recent files, preferences and unsaved work.
The signing test fixtures keep their PrintCraft subject names (they are binary).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 16:03:57 -04:00
Brandon ThomasandClaude Opus 5.5 ac222e818b Never crash: edit and xfdf have no expect calls
- edit: the substitute font name is a `&str` constant, so there's no `from_utf8(..).expect`.
  Paragraph grouping uses `let … else` / `if let` chains, and the reuse-font path takes the
  metrics with `filter` instead of `expect("checked")`.
- xfdf: a comment key that vanished between listing and lookup is skipped.

Both crates now deny the panic lints. Adds the root clippy.toml (identical to #11) so tests may
still unwrap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 14:23:06 -04:00
Brandon ThomasandClaude Opus 5.5 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 ThomasandClaude Opus 5.5 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 ThomasandClaude Opus 5.5 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 ThomasandClaude Opus 5.5 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 ThomasandClaude Opus 5.5 05195a2af6 M7: Backgrounds and watermarks from a file: an image or a page of a PDF (imported as a form XObject that draws upright, inherited resources included), scaled relative to the page, with rotation, opacity and placement; Source ▸ File in the dialogs; doc_watermark / doc_background take file, file_page and scale
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 03:44:22 -04:00
Brandon ThomasandClaude Opus 5.5 17e3eb255d M8: Redaction Properties: overlay text font (Helvetica, Times, Courier), size or auto-size, colour, alignment and repeat, written as /DA, /Q and /Repeat and drawn on apply; overlay fonts are added to the page only when used
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 03:33:01 -04:00
Brandon ThomasandClaude Opus 5.5 57980200e2 M7.4: Edit a PDF ▸ Add content: text (click and type; standard fonts, size, bold/italic, colour, alignment, wrapping) and images (PNG/JPEG/TIFF/GIF/BMP, centred at natural size) as page content that stays editable: each item is its own tagged content stream with its parameters, drawn in display space; select, move, resize (images keep proportions), double-click to retype, Format text panel, Delete; Bates numbering ▸ Add opens Header & Footer with a Bates number. content_list/page_add_text/page_add_image/content_update/content_delete tools (66 tools). Lucide align-center/right icons
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:58:03 -04:00
Brandon ThomasandClaude Opus 5.5 f8175fb97e M8.5/M8.6/M8.7: Redact a PDF: new content crate (L2: content-stream operators with spans, inline images, serializer, matrices) and redact crate (L4): Redact annotations; apply removes glyphs (TJ displacement keeps the rest in place; simple, composite/CMap and Type 3 fonts), clears covered image pixels (or removes images it can't re-encode), removes or clips vectors and shadings, rewrites form XObjects copy-on-write, removes overlapping comments, links and fields, draws the boxes with overlay text, then verifies and fails closed; redacted documents save as a full rewrite. Search & Redact text and patterns (phone, e-mail, credit card, SSN, dates). UI: Redact tool (text or box), Redact pages, Find text and redact, Set properties, Clear all / Redact all with confirmation; redact_mark/redact_apply/redact_clear tools (57 tools). Fix: deleting a field when /AcroForm is a direct dictionary
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:24:29 -04:00
Brandon ThomasandClaude Opus 5.5 4cdf74a4f2 M5.5/M6.7: Flatten comments and form fields: appearances (with /AS states) drawn into page content by Algorithm 8.1, pop-ups and replies removed, flattened widgets pruned from the field tree, links and hidden annotations kept; engine Flatten edit, comment.flatten/form.flatten commands, doc_flatten tool (50 tools)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:41:59 -04:00
Brandon ThomasandClaude Opus 5.5 d1323abaff M7.6: header & footer, watermark, background: new model (L2: page tree with inheritance, display geometry) and edit (L4) crates; marks drawn in display space on rotated pages, artifact-tagged and /PCMark-tagged (found without decompressing), original content wrapped in q/Q, page resources copied not shared; Acrobat tokens (page numbers, dates, Bates); Add/Update/Remove with exact restore of the original content; dialogs with page range options (subsets) and previews; 9 commands; tools doc_header_footer/doc_watermark/doc_background/doc_remove_marks (44 tools); dialogs outline their controls
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:03:20 -04:00