Commit Graph
21 Commits
Author SHA1 Message Date
Earl Co e5033243f4 Add fills and border widths to text boxes and callouts (#3366)
* Support fills and border widths for text comments

* Allow borderless text comment defaults
2026-10-19 13:03:27 -04:00
alexanderalber 00957b9f21 M5: Fill & Sign text reads across on rotated pages (#1710)
* M5: Fill & Sign text reads across on rotated pages

Typed text, dates and text boxes ignored the page's /Rotate, so on a
page stored sideways (common for scanned forms) the text came out
sideways. The box now follows the displayed axes, the annotation
records the turn in /PCTextRotate and its appearance is turned back
with a form /Matrix, as stamps and image signatures already do.
Callouts keep user-space axes. The headless fill_sign_add tool gets
the same layout.

generated with Claude Code

* chore: credit alexanderalber in the About window

generated with Claude Code
2026-10-15 02:21:01 -04:00
Márk BartalosandBrandon Thomas fff985f30d M5: keep stamps upright on rotated pages (#1398) (#1460)
A stamp placed on a page with /Rotate was drawn in user space, so the
label or picture turned with the page. Counterrotate the appearance so
it reads upright as the page is displayed.

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-13 01:42:57 -04:00
Zeyu LiandBrandon Thomas b91d38c073 M14: text the fonts can't draw is kept and reported, never written as ? silently (#1112)
* M14: text the fonts can't draw is kept and reported, never written as ? silently

Form values and captions, text boxes, callouts, Fill & Sign text, measurement labels and stamp by-lines keep text the standard fonts can't draw, draw ? for it, mark the annotation (PCUndrawn) and report the edit (interface notice, tools' warnings); forms set /NeedAppearances (not in PDF/A). Flattening, redaction overlay text, typed and visible signatures and create-from-text refuse instead. Reports escape such characters as [U+XXXX].

* Catalogs: the two new can't-draw messages in Czech, Slovene, Kazakh, Turkish and Greek; refresh hashes

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-11 17:53:55 -04:00
Justin WilkinsandBrandon Thomas 56c034b0b3 M9: visible digital signatures can show a drawn, typed or image graphic (#193) (#934)
* M9: visible digital signatures can show a drawn, typed or image graphic (#193)

A visible certificate signature can show a graphic where the signer's
name is large, as Acrobat's Configure Signature Appearance does: the
saved Fill & Sign signature (drawn, typed or image) or an imported
PNG/JPEG. Sign as previews it and remembers the choice; sign_document
takes `graphic` (image, text or strokes).

pdfcraft-sign gains `Graphic` and `SignOptions::graphic`. Graphics are
checked and size-capped before drawing; images keep alpha as a soft
mask and are encrypted with the rest of the update in encrypted files.

Refs #193

* Refresh catalog hashes

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-11 13:47:51 -04:00
cyfung1031 fb548a7064 fix(annot): preserve strokes with malformed interior colors (#708) 2026-10-10 06:14:21 -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
MarekSpodBiedry 5c5f4d8b49 Phone photos follow EXIF orientation; image signatures stay upright on rotated pages (#434) (#485)
* Stamps and added images follow a JPEG's EXIF orientation (part of #434)

Phones store a portrait photo as landscape pixels plus an EXIF
Orientation tag. A JPEG went into the PDF as it was (DCTDecode), and PDF
image XObjects have no such tag, so a photo used as a custom stamp, an
added or replaced image, a watermark or background, or a button image
showed up turned 90 degrees.

Before these images are embedded, a JPEG whose Orientation is not 1 is
decoded, turned the way the tag says and re-encoded (quality 92). Its
JFIF resolution is kept, swapped for quarter turns, so the natural size
on the page stays right. Other images, JPEGs without the tag, JPEGs that
fail to decode and photos over 64 megapixels are embedded unchanged, as
before. Fill & Sign image signatures already applied the tag.

* Image signatures stay upright and anchored on rotated pages (part of #434)

On a page with /Rotate 90, 180 or 270 an image signature turned with the
page, because its picture was drawn along user-space axes while the click
or the "at" argument is a displayed point. It was also anchored at the
wrong point: its left edge and vertical centre were taken in user space,
so on a 90 degree page the image centre ended up elsewhere.

The signature's appearance now carries the counter-rotation as its form
/Matrix, which viewers fit to /Rect, so the picture reads upright as
displayed. The page's rotation is kept in /PCPictureRotate, so restyling
regenerates the same matrix and moving and resizing keep it. The box of the
signature runs along the displayed axes, so its left edge and vertical
centre are where they were asked for. The page view matrix in
pdfcraft-model is split out as view_matrix_for.

The Fill & Sign preview and the live move/resize preview draw the picture
the way the appearance does, and the resize handles keep the image's
proportions as displayed. comment_image_preview reports image_rotation,
how far the image is shown turned (0 for one placed upright).

Custom image stamps are left to #473.

* Use is_multiple_of for the quarter-turn checks (clippy) (#434)

* Probe the pointer preview away from egui_kittest's drawn cursor (#434)

The kittest render paints a mouse cursor (a 16 px triangle with a black outline) at the
hover point, so the 2 pt probe beside the pointer landed on its outline when zoom and view
rotation made 2 pt only a pixel or two. Put the stroke's block at the picture's right end and
probe there and at its far margin instead.
2026-10-09 09:14:55 -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
6974c6550d Measure: add distance, perimeter and area tools (#208)
* M12: add calibrated 2D measurement tools

* M12: harden measurement tools for landing (#208)

Bounded snap targets (endpoints only for accepted segments, page-wide cap),
lenient extraction (deep q nesting and undecodable streams are skipped and
reported), per-page snap cache, measure::list reports unsupported entries
instead of failing, closed polygons with a repeated vertex, printable unit
labels (m²), cached panel listing, WinAnsi captions, indirect /VP kept,
measure.export skipped in the command test like other pickers, missing
translations, honest parity (scale and distance partial) and ROADMAP.

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

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 00:38:57 -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 ab47bf4b9a CI: as_chunks instead of constant-size chunks_exact (clippy 1.99 chunks_exact_to_as_chunks)
Stable clippy 1.99 denies chunks_exact/chunks_exact_mut with a constant
size (32 sites), which failed the test job on main and every open PR.
Behaviour unchanged; MSRV 1.90 has as_chunks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:48:43 -04:00
Brandon ThomasandClaude Opus 5.5 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 ThomasandClaude Opus 5.5 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 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 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 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 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 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 67ff9303c8 M6.1/M6.2: form filling: new fonts (L2) and forms (L3) crates; field tree with inheritance, widgets, options; set_value with validation and regenerated appearances (auto-size, comb, multiline, password, quadding, /MK, combo, list selection), check/radio states (own AP when missing), reset to /DV; engine SetFieldValue/ResetForm with fill-forms permission; UI in-place editor (Enter/click-away commit, Escape, Tab with select-all), check/radio toggle, choice popup, Clear form; tools form_fields/form_fill/form_reset. Perf: named destinations indexed once (190 MB manual opens in 1.8 s instead of 172 s); comment and form edits refresh view data from the object graph instead of a full re-inspection (6x faster per edit on large files; equivalence-tested). annot uses the shared fonts helpers. Docs, parity, roadmap.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 22:37:35 -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