Commit Graph
49 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 7163ba3dee Release 0.7.1: rebuild with the fixed shared release workflow
The previous release build failed in craft-common-actions, not in this
repo: riscv64 packaging got --formats deb,rpm,tar (fixed in
craft-common-actions#3), Linux jobs lacked the ALSA headers
(craft-common-actions#5), and Windows signing needed the AZURE_* secrets
listed in the caller.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 11:11:04 -04:00
Brandon ThomasandClaude Opus 5.5 78f00e45fe Release prep: 0.7.0
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 05:44:35 -04:00
skylar taylor-barrick 00184a1006 M10.5: Preserve main duplex-driver warnings through craft-print 2026-10-12 01:20:52 +02:00
MarekSpodBiedry 75b113ac5b Raise workspace rust-version to 1.95 to match the UI crate (#1169) (#1188) 2026-10-11 18:30:25 -04:00
skylar taylor-barrick 981a2e57c8 M10.5: Integrate main and adopt the validated craft-print spooler 2026-10-11 22:29:54 +02:00
skylar taylor-barrick 95434e9115 M10.5: Preserve composed sheets with the shared scaling and duplex API 2026-10-11 22:05:01 +02:00
21d5323132 Add faux-redaction audit (paint-order and colour-aware, fail-closed) (#110)
* Rework faux-redaction audit per maintainer review

- Paint-order aware: a rectangle counts as a cover only when painted
  strictly after the text (positions from the joined content stream).
- Colour-aware: WCAG contrast between text and cover must be below 3.0,
  so page backgrounds, table shading and highlights are not flagged.
- Fail closed: audit_redactions returns Err on undecodable content
  streams (decoded_strict) and malformed /Annots; the operator bound is
  an error, not a silent truncation.
- Graphics state carries across a page's content streams (one joined
  walk); form XObjects still isolate their state at Do.
- Audit-only: the sanitize-for-sharing half is dropped (upstream #162).
- Parity entry marked partial, not shipped.

* Audit: register its layer, add a README, fail closed past 32 nested forms, document what it doesn't check

---------

Co-authored-by: Erick Barraza <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
2026-10-11 14:32:33 -04:00
cyfung1031andBrandon Thomas 575f99f9be Add an opt-in low-disk Cargo profile (#951)
* PR-02: add opt-in low-disk Cargo profile

* PR-02: document low-disk Cargo profile

---------

Co-authored-by: Brandon Thomas <[email protected]>
2026-10-11 14:02:06 -04:00
skylar taylor-barrick c20f3aff60 M10.5: Adopt shared craft-print system spooler 2026-10-11 07:29:54 +02:00
skylar taylor-barrick ae4f5d44f3 Merge pull request #966 from skylartaylor/codex/ui-suite-integration-20261010
Adopt shared panel docking with document-aware visibility
2026-10-10 20:03:37 -06:00
Brandon ThomasandClaude Opus 5.5 53a5880386 Bump to 0.6.0; add a Linux riscv64 release build (#945)
- Cargo.toml: [workspace.package] and the internal path-dependency requirements move to 0.6.0
  (they pinned 0.5.0, which `cargo update -w` can't match); Cargo.lock refreshed.
- release.yml: new `linux-riscv64` job, ported from GridCraft. Cross-compiles on ubuntu-24.04
  against ports.ubuntu.com riscv64 libs (the linux job's -dev packages, :riscv64), builds the
  tar.gz and the CLI-only tar.gz, smoke-tests pdfcraft-cli under QEMU, and is in the draft
  release job's needs, so SHA256SUMS covers it.
- packaging/linux/package.sh: CROSS_ARCH / CROSS_TARGET / CROSS_COMPILE / EMULATOR support.
- README and docs/releasing.md list the riscv64 tarballs (glibc 2.39+).
- contributors.json refreshed.

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-10 20:50:57 -04:00
skylar taylor-barrick 8ff27dc86e UI.9: preserve PDFCraft panels and document lifecycle 2026-10-10 15:46:23 -06:00
Brandon ThomasandClaude Opus 5.5 fb46909e3f Bump version to 0.5.0 (from 0.4.0) for release; refresh contributors
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 21:02:20 -04:00
f7d5ca4a07 Windows: a window larger than the GPU's texture limit can't close PdfCraft (#577) (#609)
* Windows: vendor egui-wgpu 0.36.2 as published (#577)

The crate as released on crates.io, plus egui's LICENSE-APACHE and
LICENSE-MIT from the 0.36.2 tag (the published crate leaves them out).
Not used yet: the next commit patches it and adds it to [patch.crates-io].

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Windows: a window larger than the GPU's texture limit can't close PdfCraft (#577)

egui-wgpu 0.36.2 configures a window's surface at the window's own size.
Beyond the device's max_texture_dimension_2d, Surface::configure fails
validation and wgpu's default error handler panics. eframe configures the
surface before the app is created, so no app code can intercept it
(emilk/egui#8361). #578 raised the device's limit to the adapter's; this
removes the crash for windows larger than even that.

vendor/egui-wgpu: `winit::surface_fit` shrinks both sides by one factor so
neither exceeds the limit (the longer side lands exactly on it), and egui
draws at that factor into the surface. On DX12, PdfCraft's Windows default,
the swapchain is stretched over the window (DXGI_SCALING_STRETCH), so the
window stays complete and lined up with the pointer, only softer; wgpu's GL
backend copies it unscaled into a corner instead. It applies wherever a
surface is sized: install, resize (start-up restore, maximise, DPI change,
fullscreen) and a recreated surface, which starts again from the window's
own size. Depth and MSAA textures follow. A surface logs a warning when
it becomes fitted.

Why only an Outlook launch hit it (read from the code, not observed):
winit creates the window at CW_USEDEFAULT, so Windows places it, and a
launcher that hands ShellExecute its own window gets new windows on its
monitor. winit then converts the restored logical size at that monitor's
scale: 3440 points became 8600 pixels on a 250% panel. eframe's clamp
compares points against the largest monitor, so it let 3440 through.

Tests: surface_fit with the issue's 8600 x 3423 and edge sizes (zero,
u32::MAX, a zero limit, the longer side exactly on the limit); egui-wgpu
resolves to vendor/egui-wgpu and the fit stays wired into the paths that
size a surface.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* vendor/egui-wgpu: drop the stray .cargo-ok marker

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
2026-10-09 18:54:10 -04:00
cyfung1031andClaude Opus 5.5 24ba8385f8 Issue #324: on Windows 11, a window dragged to another monitor takes its scale (#544)
* Issue #324: vendor winit 0.30.13 as published

The crate as released on crates.io, without its asset files (docs/res/*.svg and
examples/data/*.png, AGENTS.md §1). Not used yet: the next commit patches it and
adds it to [patch.crates-io].

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Issue #324: on Windows 11, a window dragged to another monitor takes its scale

winit 0.30.13 handles WM_DPICHANGED by checking that the new window rect is on
the monitor `MonitorFromWindow` names. During a drag that is still the monitor
being left, so winit nudged the window back onto it, which sent another
WM_DPICHANGED: the window grew and stayed on the wrong monitor at the wrong
scale. From Windows 11 (build 22000) on, apply the rect Windows suggests, as
winit master does since 488c036a (rust-windowing/winit#4341); no 0.30 release
has it. Windows 10 keeps the old adjustment, as on winit master.

The vendored copy goes in [patch.crates-io]; a test fails if winit resolves
from crates.io again or the vendored copy loses the patch.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-09 12:19:41 -04:00
Brandon ThomasandClaude Opus 5.5 e5b37b8b9e Fix #454: dependencies keep only line tables in dev builds (#559)
On Windows every integration-test binary links the whole app and gets its
own 500-600 MB PDB, mostly debug info for third-party crates, so one
`cargo test --workspace` needs ~38 GB of target dir.

[profile.dev.package."*"] now sets debug = "line-tables-only". "*"
matches only non-workspace packages (crates.io dependencies and the
vendored crates under vendor/, which are excluded from the workspace), so
our own crates keep full debug info and dependency frames still show file
and line in backtraces.

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-09 11:48:03 -04:00
69fa2ea9f8 Platform: one save-staging helper for automation and the desktop app (#356)
Follow-up to #319, from review. create_staging, staging_suffixes and
STAGING_ATTEMPTS were copied in pdfcraft-automation and pdfcraft-ui-egui,
which are both L7 and can't depend on each other. They now live once in
the new pdfcraft-platform crate (L7, std only), which layers.rs already
reserved with both sideways edges.

A pure move: the body is unchanged apart from a StagingName parameter
that keeps each caller's existing file name (.{name}.{suffix}.pdfcraft-tmp
for automation, .{name}.pdfcraft-{suffix}.tmp for the desktop save). The
doc comment on staging_suffixes now says the suffix is SipHash keyed from
the OS random source: enough that a name can't be planted in advance, but
not a CSPRNG.

New tests in the platform crate pin both name forms, the 128-byte stem
cut, the 16-name limit and refusal when no suffix is left. The callers'
planted-file, link, folder and failed-rename tests stay where they are.

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
2026-10-08 17:07:00 -04:00
Brandon ThomasandClaude Opus 5.5 96c58f6f44 Bump version to 0.4.0 (from 0.3.0) for release
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 10:01:50 -04:00
Brandon ThomasandClaude Opus 5.5 ed2e34950c Bump version to 0.3.0 (from 0.2.1) for release
The internal path dependencies carry an explicit version requirement, so they move to 0.3.0 too.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 08:13:58 -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 <[email protected]>

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-08 00:38:57 -04:00
42ddb2d546 XFA: lay dynamic forms out from their template and keep their data in step (#60) (#121)
* M12: lay dynamic XFA forms out from their template (#60)

A dynamic XFA form is a PDF shell around an XML template: one placeholder
page ("requires Adobe Reader") and /NeedsRendering true. Every viewer
without an XFA engine shows the placeholder, and so did PrintCraft.

New crate printcraft-xfa (L3, already reserved in the layering table). It
reads the XDP packets, parses the template (XFA 3.3: subforms, areas,
fields, draws, exclusion groups, page sets, fonts, paragraphs, borders,
captions, rich text, inline JPEGs, occurrences, breaks, overflow leaders,
column widths), lays it out (positioned, tb, lr-tb, table/row; containers
without a width size to their content; flow across content areas and page
masters; header rows repeat after a break; hidden takes no space; page
number and count fields resolve) and writes real pages and AcroForm
widgets into the document: text, date (AFDate format and keystroke
actions from the picture clause), check boxes, radio groups, push buttons
with reset/print/save/URI actions. Standard-14 fonts stand in for Arial,
Courier New and friends; nothing is embedded.

The engine lays a dynamic form out when it opens it. The original bytes
stay: the layout is one appended revision, the widgets get appearances
from the forms crate, and the XFA packets remain so Adobe's viewers keep
rendering the form their way. A marker on the AcroForm (/PCXfaLayout)
stops a saved form from being laid out twice; each field keeps its SOM
path (/PCSom) for the data round trip to come. doc_info, the CLI's info
and the notice bar report the layout.

Checked on IRCC's IMM 5669 (Schedule A, Designer 6.2, 464 KB template,
AES-encrypted, usage rights): four pages and 308 fields in 27 ms, the
same page structure as the form, filled through form_fill, saved in
place with the original bytes intact and reopened with the values.

Not done, and said so in the parity notes: the datasets packet is neither
read nor written, so Adobe's viewers don't show values filled in here;
no FormCalc or XFA JavaScript (rows don't grow, nothing calculates);
choice lists are text fields; signature, image and barcode fields are
blank; metrics are approximate and fidelity is eyeballed, not measured.

Tests: crates/xfa (parsing, sizing, pagination with repeated headers,
PDF writing, hostile input), the engine (open, fill, incremental save,
reopen without a second layout), the automation tools (open, info,
render, fill, save, reopen) and the UI notice (kittest).

* M12: XFA forms read and write their datasets packet; static forms too (#60)

With the layout alone, a form filled in PrintCraft opened blank in Adobe
Reader, and one filled in Acrobat opened blank here: Adobe's viewers keep
the values in the XFA datasets packet, not in the AcroForm fields.

The xfa crate's new data module reads the datasets packet (normal binding:
a field's node is named after it under its named ancestor subforms,
repeated instances as repeated siblings) and writes it back from the
fields. Laying a form out now takes each field's value from its data node
(dates in ISO form shown in the field's pattern, check boxes and radio
groups by their on values) and gives a repeating subform or table row as
many instances as the data has, so rows another viewer added appear.
Every laid-out field carries its SOM path and its on/off items, so the
packet can be rebuilt from the AcroForm at any time.

The engine writes the datasets after every form edit (one revision with
the field change), and on open applies the datasets to the fields of a
static XFA form, or of a dynamic one laid out earlier, when another
viewer changed them since. The static-form notice now says the two are
kept in step instead of warning that Acrobat may disagree.

Checked on IRCC's IMM 5669: fill, save in place (original bytes intact),
and the file holds <IMM_5669><page1><familyName>SINGH</familyName>…, the
structure Acrobat writes for this form; reopening shows the values.

Not done: explicit bind refs, global binding and data descriptions are
not followed; no import or export of standalone XML or XDP data files.

* M12: XFA layout memoizes container sizes, bounding measurement work (#60)

A container without a width measured its content for its width and again for its
height at every level, so nested width-less subforms took 2^depth measurements, all
synchronously in Session::open. Container sizes are now cached per (node, width,
depth), the root and page-area items keep stable addresses instead of being cloned
per measurement, and a measurement budget turns anything left into TooLarge.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* M12: rustfmt the merged XFA notice (#60)

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* M12: XFA datasets are merged into, not replaced; capped; UTF-16 kept; rewrites recorded (#60)

- write_datasets merged nothing: it replaced <xfa:data> with the AcroForm-bound values
  alone, dropping unbound, namespaced and deep data. It now edits the existing packet
  text in place: a bound node's text is replaced only when it differs, missing nodes are
  added below the deepest existing one, and everything else (unbound data, other
  namespaces, attributes, comments, layout) stays byte for byte. A packet of an XFA array
  that relies on the envelope's prefixes is read inside a wrapper declaring them.
- What can't be written (a node holding structured content, too-deep paths or absurd
  SOM indices, conflicting fields, an unreadable or non-UTF packet) comes back as
  DatasetsWrite.warnings; the engine keeps them in Document.xfa_warnings and
  info.warnings (surviving re-reads), and doc_info reports xfa_warnings.
- Building data counted same-name siblings for every one it added (quadratic in an
  untrusted index) with no total cap. Children are now indexed by name, indices above
  10,000 and paths deeper than 64 are refused, and one write creates at most 20,000 nodes.
- Packets are decoded exactly (UTF-8, UTF-16 LE/BE with or without BOM) and written back
  in the encoding they came in; anything else is reported and left untouched instead of
  being rewritten from a lossy UTF-8 reading.
- A static XFA form whose fields are rewritten from the datasets on open now says so in
  info.warnings, naming the fields.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-07 23:24:54 -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 <[email protected]>
2026-10-07 16:03:57 -04:00
Brandon ThomasandClaude Opus 5.5 30f09f2f9b Release: PrintCraft v0.2.1
Fixes the Windows installer: the Start Menu shortcut and Add/Remove Programs icon were blank. (printcraft#57)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 08:02:34 -04:00
Brandon ThomasandClaude Opus 5.5 6e90710e4b Never crash: JBIG2 images can't decode billions of pixels
The nightly fuzz job found a JBIG2 symbol dictionary that decoded for
minutes: each bitmap side may be 65535, and up to 65535 symbols are decoded
pixel by pixel. Vendored hayro-jbig2 0.3.0 with two bounds: at most 2^28
pixels per bitmap (also the page bitmap, halftone grid and grayscale image),
and at most 2^26 symbol pixels per dictionary. The finding now finishes in
about a second. Synthetic regression test (a 65535 x 65535 page and region
behind a small /Width and /Height); the corpus sweep shows 0 regressions.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 08:28:52 -04:00
Brandon ThomasandClaude Opus 5.5 df3457ed92 Release: PrintCraft v0.2.0
Bump the workspace version 0.1.1 -> 0.2.0 (cargo xtask version set 0.2.0).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 02:40:53 -04:00
Brandon ThomasandClaude Opus 5.5 1449b71a19 Never crash: bound the allocations behind the nightly fuzz runner's out-of-memory deaths
Fuzzed inputs drove one check-one process to 2-6 GB (the 16 GB CI runner
running two of them was killed every night). Three causes, each with a test:
- lopdf (bootstrap inspector) sized PNG predictor rows from /Columns before
  reading data: /Columns 4294967295 allocated two 4 GiB rows. Vendored lopdf
  0.45.0 refuses rows longer than the data (and uses saturating row widths);
  its load-time stream decoding also gets a 256 MiB limit (it had none).
- hayro sized a tiling pattern's cell pixmap from /XStep x scale, bounded only
  by u16: a step far beyond /BBox allocated 2 GB. The vendored patch keeps
  the cell within 3000 px a side, lowering the resolution instead.
- cos decoded cross-reference streams up to the general 1 GiB limit; they now
  stop at what 8,388,607 objects' rows can hold (~200 MB at most), and the
  section is reconstructed (logged) instead.

On the nightly's seed (41) the worst captured input fell from 6.2 GB to 6 MB,
and a 300 s fuzz run had no process above 300 MB (before: many at 2-5 GB).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 17:59:25 -04:00
Brandon ThomasandClaude Opus 5.5 554969da72 Never crash: forbid unsafe, clippy.toml for tests, guard and craftrules link
Follows the owner's AGENTS.md §4 / CLAUDE.md rules with what the shared standard
(craftrules/standards/never-crash.md) adds: why (lost work) and that it outranks feature work,
the `unsafe` ban (workspace `unsafe_code = "forbid"`; no unsafe exists outside vendor/),
the last-resort guard around commands and file import/export, the clippy ratchet attribute,
and a root clippy.toml that lets tests use unwrap/expect/panic/indexing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 13:24:00 -04:00
Brandon ThomasandClaude Opus 5.5 9d99f4b278 Release 0.1.1
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 09:55:41 -04:00
Brandon ThomasandClaude Opus 5.5 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 <[email protected]>
2026-10-03 09:40:46 -04:00
Brandon ThomasandClaude Opus 5.5 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 <[email protected]>
2026-10-03 07:19:54 -04:00
Brandon ThomasandClaude Opus 5.5 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 <[email protected]>
2026-10-03 05:31:18 -04:00
Brandon ThomasandClaude Opus 5.5 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 <[email protected]>
2026-10-03 04:41:47 -04:00
Brandon ThomasandClaude Opus 5.5 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 <[email protected]>
2026-10-03 03:47:58 -04:00
Brandon ThomasandClaude Opus 5.5 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 <[email protected]>
2026-10-02 05:05:56 -04:00
Brandon ThomasandClaude Opus 5.5 9fcece8afb M11.1: PDF Optimizer: new optimize crate measures each image's effective resolution where pages draw it and resamples (bicubic) and recompresses (JPEG quality steps or ZIP) colour and grayscale images, soft masks with them, only when smaller; discards thumbnails, alternate images, tags and print settings; Flate for unencoded streams. Reduce File Size now downsamples like Acrobat (150 ppi above 225, JPEG medium); Optimize PDF dialog (Images, Discard Objects, Discard User Data, Clean Up) composes Remove Hidden Information; doc_optimize tool (84 tools)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 03:18:47 -04:00
Brandon ThomasandClaude Opus 5.5 e06a98adaa M9.1–M9.3: new sign crate: DER, X.509, CMS SignedData, PKCS #12 (PBES2 and legacy, MAC) on RustCrypto with aws-lc-rs for RSA private keys; PAdES B-B signing (new or existing field, visible or invisible, DocMDP certification) with an incremental placeholder save; validation (digest, signature, chain against a trust store, changes after signing classified under DocMDP); checked against pdfsig and OpenSSL
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 02:43:46 -04:00
Brandon ThomasandClaude Opus 5.5 22a8691475 M5.6/M6.7: Comment and form data exchange: new xfdf crate (L4): XFDF (ISO 19444-1) export/import of comments (replies, pop-ups, ink, quads, line ends, flags, colours) and nested field values; FDF both ways; form data as Acrobat XML, CSV and tab-delimited text. Import replaces comments with the same name and sets values through formats/validation (read-only fields take data). Import/Export commands; doc_export_data/doc_import_data tools (69 tools)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 01:31:56 -04:00
Brandon ThomasandClaude Opus 5.5 2aa29254da M10.5: Print: new print crate (L4) imposes the pages to print onto sheets (Fit/Actual/Shrink/Custom, Multiple pages per sheet with order, borders and auto-rotate, Booklet, Poster with overlap and cut marks, orientation, Comments & Forms honouring the Print flag) as a fresh print-ready PDF; page ranges with labels, odd/even, reverse; CUPS spooler (printers, copies, collation, duplex, monochrome). Print dialog (⌘P) with a live sheet preview from page thumbnails and Save as PDF; print permission enforced; printers/doc_print tools (61 tools)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 00:40:57 -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 <[email protected]>
2026-10-02 00:24:29 -04:00
Brandon ThomasandClaude Opus 5.5 adb644c5e1 M10.2/M11.1: Create a PDF (blank, from PNG/JPEG images at their resolution with transparency, from plain text) in a new create crate (L4); opening an image or text file converts it to a new unsaved PDF; Reduce file size (resource merge across the document, GC, object streams) writes a compact copy; Create group Ready; doc_create/doc_reduce tools (49 tools). Fix: the Hand tool did not pan (the page widget took the drag)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 23:29:17 -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 <[email protected]>
2026-10-01 23:03:20 -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 <[email protected]>
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 <[email protected]>
2026-10-01 20:44:19 -04:00
Brandon ThomasandClaude Opus 5.5 2849ad8922 M2.6: vendor hayro-syntax 0.7.2 with a page-tree cycle guard (stack overflow on /Kids loops in object streams)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 08:43:41 -04:00
Brandon ThomasandClaude Opus 5.5 19788d3336 M0.4/M0.5: deny.toml + xtask deny in ci, GitHub CI workflow; MCP module behind a Cargo feature
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 23:45:10 -04:00
Brandon ThomasandClaude Opus 5.5 88e4ca7e5b M13.1: printcraft-automation (headless tool set + opt-in MCP server over stdio); M4.8: CLI tools/run/mcp
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 23:32:23 -04:00
Brandon ThomasandClaude Opus 5.5 5f5f83cc0c Session 4: M1.6 encryption (crypt crate R2-R6), M4 command registry, combine/extract/split, autosave + crash recovery, asset policy + xtask assets, README screenshots
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 23:12:34 -04:00
Brandon Thomas 108fdc108c more progress, roadmap, wip 2026-09-30 11:00:02 -04:00
Brandon Thomas f0b5f8ff55 one-shot first ver 2026-09-30 05:17:08 -04:00