Commit Graph
17 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 275cbcf323 Refs #169: no form bar for push-button-only documents; Screen is not a comment (#615)
LaTeX `animate` PDFs store each frame as a read-only push button and drive
them from a Screen annotation. PdfCraft showed "This document contains N
interactive form fields." because the bar counted any field, and listed
the Screen annotation in the Comments panel because only Link, Widget and
Popup were filtered out.

- The form-fields bar now needs at least one field that isn't a push
  button (something to fill in).
- Non-markup annotations (ISO 32000-2 §12.5.6: Screen, Movie, RichMedia,
  3D, PrinterMark, TrapNet, Watermark) are no longer comments, both when
  a document is inspected and when the comment list is rebuilt after an
  edit (new pdfcraft_annot::is_comment_subtype).

Playing the animation itself (page actions, timers) is out of scope here.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 17:49:54 -04:00
9a529a4fbe Preserve alternate appearances and indirect push-button values on redraw (#417)
* D5: README for cos and engine, and an honest cos status line

Thirteen crates have no README, although the session protocol tells every session to read the README of the crate it is touching. These are the two biggest: cos is where every hostile file lands first, and engine is the whole API surface a frontend gets.

Each states its layer and the rules that bind it, sketches the API against the real signatures, and ends with what is deliberately not done. The cos README spells out the clone-is-a-snapshot property and why both writers return bytes rather than taking a sink; the engine README spells out the four-step editing model that makes what you see what Save writes.

Also corrects the module doc on cos/src/lib.rs, which still said encryption and object-stream output for full saves were not done. Both shipped: security.rs handles R2-R6 with crypt filters and /EFF, and SaveOptions::object_streams defaults to true.

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

* Preserve alternate appearances and indirect push-button values

Keep rollover, down and custom appearance entries when normal appearances are regenerated, without modifying shared dictionaries. Resolve indirect button caption and layout values. Cover full and incremental saved output, and wait for raster readiness in the existing Linux scroll test.

Co-authored-by: Codex <codex@openai.com>

* M14: let neutral Windows locales fall through to display language

Co-authored-by: Codex <codex@openai.com>

* pdfcraft-cli --help lists `mcp` only when the build has it

Follow-up to #540: a build without the `mcp` feature (`--no-default-features`) still listed
`pdfcraft-cli mcp` in its usage, and `pdfcraft-cli mcp` then said "unknown command".

USAGE is now put together with `concat!`, and its `mcp` lines come from a macro that is empty
without the feature. In such a build `pdfcraft-cli mcp` says the MCP server was left out instead
of calling it an unknown command.

- tests/help.rs: usage_lists_mcp_only_when_built_with_it (runs in both feature sets) and
  mcp_without_the_feature_says_it_was_left_out (without the feature)

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

* engine README: the execution plan is local-only, so don't link a path that doesn't exist

---------

Co-authored-by: Tanish Manku <tmanku.dev@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: sanyamsingh001 <314051937+sanyamsingh001@users.noreply.github.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Streetblock <github@streetblock.de>
Co-authored-by: lloyd <lloyd@stackworx.io>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-09 14:45:32 -04:00
Márk BartalosandBrandon Thomas 3af93c7585 M5: draw all ten PDF line-ending styles (#520)
* M5: draw all ten PDF line-ending styles

Imported lines, polylines and callouts kept Square, Circle, Diamond, Butt, Slash and reverse arrows in /LE but would not redraw them. Those styles now draw, and comment_add and Comment properties can set them.

* hu, uk: Line ending

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-09 13:15:44 -04:00
07b95409bf Comments without an appearance stream are drawn (display only, never saved) (#371)
* M5: comments without an appearance stream are drawn (display only, never saved)

#260 (page 7): a FreeText box with /DA and an orange /C background, a
Text note and an Ink stroke, all without /AP, were not drawn; Acrobat,
MuPDF, PDFium and Poppler draw them. The renderer only draws /AP (plus
the Highlight fallback of #274), and pdfcraft-annot, which already
draws all of these for PdfCraft's own comments, can't be used from the
renderer (both are L3).

pdfcraft_annot::with_missing_appearances returns a copy of the document
in which every annotation without /AP /N that appearance::build can
draw (FreeText, Ink, Text, FileAttachment, stamps, shapes, lines,
markup, …) has the appearance build draws from its dictionary; links,
form fields and pop-ups are left alone, as is anything build declines.
The engine keeps that copy, written as an in-memory incremental update,
in a new Document::display: the page view's render pool, page_render
and page images (export_source) read it. Document::bytes, what Save,
signatures and the inspector use, is unchanged. display is rebuilt
wherever the renderer was (open, refresh, scoped refresh) and is bytes
itself when nothing is missing or the document can't be edited.

Tests: annot tests::comments_without_appearances_get_one_for_display_only
(FreeText, Ink and Text get /AP /N in the copy, an existing /AP is kept,
Link, Widget and an unknown subtype aren't touched, the original is
untouched, none means no copy) and engine
tests::comments_without_appearances_are_drawn_but_not_saved (the page
view draws the FreeText background and the Ink stroke, before and after
an edit; the working bytes stay the opened file; Save writes no /AP).
On main the page view shows white where the FreeText box is. Parity:
view.render-annotation-appearances cites the test and notes what's left
(Link borders without /AP, printing).

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

* Test the Ink stroke on its apex row: Ink is now a curve through its points (#374)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-08 19:43:58 -04:00
5ef27ff678 M5: ink strokes are drawn as smooth curves through their points (#374)
#260 (page 7) compares PdfCraft with Acrobat, which draws an Ink
annotation's /InkList as a smooth curve through the points;
pdfcraft-annot drew straight segments between them (as MuPDF, Poppler
and PDFium do). A stroke of three or more points is now drawn as a
Catmull-Rom spline through every point, written as cubic Béziers: the
curve leaves each point parallel to the chord between its neighbours,
and an end uses itself as the missing neighbour. Two points stay a
line and one point a dot. This is the appearance PdfCraft writes for
its own ink, signatures drawn with Fill & Sign included, and, with the
display-only appearances for comments that have none, how ink without
/AP is shown.

A curve can swing beyond its points, so a new ink annotation's /Rect
now also covers the curve's control points (the curve stays within
them); before, only the points plus the line-width margin.

Test: annot tests::ink_strokes_are_smooth_curves_through_their_points
checks the exact curve for a three-point stroke, a line for two points,
a dot for one, and a /Rect that holds a stroke whose curve rises above
its highest point (22 on main, 23.667 now). The comment.pencil parity
entry cites it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-08 18:58:17 -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
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 ThomasandClaude Opus 5.5 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 ThomasandClaude Opus 5.5 e0d954f10a M5: Eraser for drawings (Draw flyout): rubs out the parts of ink strokes it passes over, splitting strokes and deleting emptied drawings, in one undo step
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:12:36 -04:00
Brandon ThomasandClaude Opus 5.5 968d26a41e M5: Attach a file as a comment (push pin, paperclip, graph or tag icon in PrintCraft's own drawings; the file is embedded and listed under Attachments); comment_add type attachment
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:09:44 -04:00
Brandon ThomasandClaude Opus 5.5 bf58d1f6bf M5: Area highlight (drag the highlighter off text) and Replace Text (strikeout plus a grouped caret holding the replacement; Highlight flyout, comment_add type replace)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 04:05:25 -04:00
Brandon ThomasandClaude Opus 5.5 7616535dd1 M5: Polygon, Connected lines, Cloud (cloudy border appearance), Callout (leader line with arrow, /RD text box, resize re-attaches the leader) and Insert text (caret) comments: annot shapes and appearances, click-to-place-points and drag-to-callout tools in the Comment/Highlight/Draw flyouts, /IT carried to the comment list (Callout, Cloud labels), comment_add types polygon/cloud/polyline/callout/caret
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 02:11:52 -04:00
Brandon ThomasandClaude Opus 5.5 ed8a002465 M7: Links: Link tool (drag to create; outlines, select, double-click for Link Properties, Delete), Link Properties (visible/invisible, highlight, thickness, style, colour; go to a page or open a web page), Create links from URLs in the text, Remove all links; link_list/link_add/link_edit/link_delete/links_from_urls/links_remove tools (75 tools)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 01:49:33 -04:00
Brandon ThomasandClaude Opus 5.5 f31d89bc9d M5: Add a stamp: palette of Dynamic (By author at time, date), Sign Here and Standard Business stamps in PrintCraft's own design (ISO stamp names where defined; foreign stamps keep their artwork); click to place; comment_add type stamp
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 01:37:13 -04:00
Brandon ThomasandClaude Opus 5.5 245c468bc7 M5.4: Comment Properties (appearance: colour, opacity, thickness, note icon; general: author, subject; review history) from the canvas and card menus, one undo step; Comments panel filter (type, author, status) and sort (page, author, date, type, colour) with group headers; annot set_info/props
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:35:30 -04:00
Brandon ThomasandClaude Opus 5.5 2c69c02699 M5.7: Fill & Sign: typewriter text, check/cross/dot/line marks (PrintCraft-drawn stamps), today's date (local time), drawn signature (signature pad, saved in settings, placed by click); quick-bar Fill & Sign flyout, 7 commands, catalog Ready; fill_sign_add tool (47 tools) for agents filling flat forms; local UTC offset via chrono (already in the graph)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:21:11 -04:00
Brandon ThomasandClaude Opus 5.5 4058c156f7 M5.1/M5.2: comments engine: new annot crate (L3) with builders and appearance streams for sticky note, highlight, underline, strikeout, squiggly, rectangle, oval, line/arrow, ink, text box; reply, review status, move, resize, restyle, delete (with pop-ups and replies); undoable engine edits with /NM ids and dates, annotate-permission check; inspector reports index, state, quads; 6 automation tools (comment_list/add/reply/set_status/edit/delete, highlight by text search)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:44:19 -04:00