- A scan drawn only through grouped Form artwork is reported in skipped
(once per form, with every page that draws it) instead of being counted
as no scan; a Form of vector artwork holding only a small picture
(under 36 dpi over its area) still counts as no scan.
- decode_samples checks the filter before the colour space and bit depth,
so a JPEG 2000 image without /ColorSpace or /BitsPerComponent is
reported as JPEG 2000, not as a colour-space or bit-depth problem.
- Optimize and Enhance scanned file no longer start while the other runs:
they share the progress card and capture the same document state.
- docs/gaps.md: background and edge-shadow removal apply to grey and RGB
scans, despeckle also to 1-bit ones.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scan & OCR ▸ Enhance scanned file (Acrobat's Enhance ▸ Scanned document)
now cleans up scanned pages: background removal (the camera clean-up's
level 0-100), edge shadow removal (book gutters, copier borders) and
despeckle, each its own switch.
The camera tool renders the page and replaces it with a picture, which
would drop a scan's invisible OCR text, comments and links. Instead each
scan image (pictures covering at least half the page, each at least a
tenth) is decoded, cleaned and written back into its own image object at
the same size and colour space: a JPEG stays a JPEG (quality 90), other
grey/RGB images are stored losslessly, a 1-bit image stays 1-bit with its
decode array, and every other dictionary entry (SMask, Interpolate, ...)
is kept. An image several pages share is cleaned once. What can't be
cleaned (CMYK, indexed, JPEG 2000, JBIG2, CCITT, colour-key masks, broken
data, oversized images) is reported, never skipped silently; pages that
are no scan are listed too.
The engine works as a job like Optimize (scan_clean_job, run on a worker
with progress and cancel, apply_scan_clean refuses a result for an older
document state) and applies one undoable step, "Enhance scanned file".
pdfcraft-optimize exposes decode_samples/encode_samples for in-place
pixel edits. camera_clean gains clean_samples for grey and RGB samples
with separate switches and an edge-shadow pass; the camera tool's output
is unchanged. page_enhance_scan drives it headlessly.
Not yet an option of Recognize text. Refs #4119.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
craft-libs#366 drops the default-features override on craft-keymap that
older Cargo rejects. FreeBSD aarch64 builds with Rust 1.98.1 and failed
with "no matching package named craft-menu found" (craft-libs#364).
* Refactor annot for strict Clippy checks
* Refactor automation for strict Clippy checks
* Refactor cos for strict Clippy checks
* Refactor edit for strict Clippy checks
* Refactor engine for strict Clippy checks
* Refactor export for strict Clippy checks
* Refactor forms for strict Clippy checks
* Refactor js for strict Clippy checks
* Refactor organize for strict Clippy checks
* Refactor pdfcraft-cli for strict Clippy checks
* Refactor preflight for strict Clippy checks
* Refactor print for strict Clippy checks
* Refactor redact for strict Clippy checks
* Refactor render for strict Clippy checks
* Refactor sign for strict Clippy checks
* Refactor ui canvas for strict Clippy checks
* Refactor ui commands for strict Clippy checks
* Refactor ui dialogs for strict Clippy checks
* Refactor ui support for strict Clippy checks
* Refactor ui tools for strict Clippy checks
* Refactor ui workflows for strict Clippy checks
* Refactor xfa for strict Clippy checks
* Refactor xfdf for strict Clippy checks
* Enforce workspace Clippy standards and document lint policy
* Fix menu overflow and form pointer handling
* Group annotation, form and document operation parameters
* Group signing and timestamp validation inputs
* Group demo form field properties
* Group UI interaction and rendering parameters
* Restore translated security and shortcut labels
* Fix platform-gated imports for Windows and wasm builds
* Qualify signing calls for macOS and Windows builds
* Restore the preflight check flow and the overflow menu title
The pre-signing check matched any folder named Program Files, so it rejected
a valid MSI when Windows resolves Program Files elsewhere, accepted the 64-bit
root for an x86 package and accepted a different app name. Build the expected
folder from the package architecture's resolved root and the policy name.
Export > Image spent its time in the PNG, JPEG and TIFF encoders, one
page after another: on a 55-page manual at 150 dpi, drawing every page
took about 0.34 s and encoding it 1.1 s (PNG) to 2.0 s (JPEG).
Exporter::images exports a list of pages, drawing and encoding several
at once on worker threads, each with its own PageRenderer (as
automation's extract_parallel does), and hands the files to a sink in
page order on the calling thread. Workers draw at most one page ahead
of the sink and fewer run when 1 GiB can't hold that many of the
largest page. The first page or sink error stops the export with every
earlier page handed over, as before. A page panic becomes that page's
error, and a panicking sink stops the workers. One page, one core or
wasm keeps the per-page loop. Export > Image and the doc_export_images
tool use it.
Files are byte-identical. One core is left for the interface (at most
8 workers). With examples/export_bench, on a Ryzen with 16 threads
(shared), mean of two medians of 21 runs:
PNG 150 dpi 1874 -> 340 ms (-82%)
JPEG 150 dpi 2106 -> 340 ms (-84%)
TIFF 150 dpi 2032 -> 375 ms (-82%)
PNG 300 dpi 3804 -> 590 ms (-84%)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Real msiexec runs (per-user and all-users, silent and wizard) found two defects
that the metadata fixtures cannot see:
- "Only for me" published ALLUSERS=2, so FindRelatedProducts treated the run as
per-machine and skipped the existing per-user copy. An interactive upgrade
left two registered products and uninstall left files behind. The page now
leaves ALLUSERS unset for a per-user choice.
- Windows Installer resolves Program Files once, for the context it started in,
so choosing "Everyone" in the wizard installed into the user profile with a
machine-wide registration. The wizard now sets the new-install folder itself
after the choice (Program Files, Program Files (x86) for 32-bit, or the
per-user Programs folder). Silent installs are unchanged.
check-install-policy.ps1 now fails if either regresses.