* M10: the Print dialog remembers two-sided, grayscale, collate, sizing and comments & forms (#2001) Persist the choices that describe how this computer prints and restore them on the next launch, under the names doc_print takes; copies, pages, layout, orientation and the printer still start fresh for each job. Those names now live in one place, pdfcraft_print::names, used by the tool and the settings file. Settings are untrusted: an unknown name or a custom scale outside the dialog's 1..=1000 % keeps the default. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * M10: the Print dialog also remembers a booklet's binding side (#2707) Acrobat keeps the booklet binding (left or right) between prints; PdfCraft started at Left every time. It is now kept with the other remembered print choices, named as doc_print names it, and an unknown saved value keeps the default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M10: Print starts each job's copies, pages, layout and orientation afresh (#2001) CodeRabbit on #2103: the README promised that copies, pages, layout and orientation start fresh, but open_print carried them over through `..keep` within a session. ISO 32000-2 Table 147 initialises these per document when the print dialog opens (NumCopies "typically 1", PrintPageRange), so each opening now resets them to the defaults (Selected pages still win when thumbnails are picked); two-sided, grayscale, collate, sizing, Comments & forms, binding, the paper and the printer picked last carry over as before. Two-sided names now include "printer" (leave it to the printer, main's default since #2422), so that choice is remembered too. main's paper-persistence test expected grayscale not to persist; it is one of the remembered preferences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M10: a new print job also resets its layout's own options and leaves Label (#2001) CodeRabbit on #2103: resetting the layout to Size kept pages per sheet, order, borders, booklet subset and the poster options through `..keep`, so choosing Multiple again brought back, say, a cut-and-stack order; and a job printed on Label went back to Size without giving back the paper Label replaced. open_print now leaves Label through set_handling (#3564) and resets the layout's own options with the rest of the job's choices; the binding and sizing stay remembered. The README now says what resets on each opening and what carries over. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M10: the Print dialog also remembers Print as image and its resolution (#6392) A printer that needs pictures keeps getting them after a restart: as_image and dpi are saved with the other print preferences and restored, a resolution the dialog doesn't offer keeping the default 300 dpi. The bad-settings checks move to their own test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pq7HyDBXygTf7jcqdsjcfn --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: mtlcl410 <chuanlin@niar.org.tw>
7.2 KiB
pdfcraft-print
Layer L4: printing (execution plan M10.5).
let pages = select_pages(count, Some("1-3, ii, 9-"), &labels, Subset::All, false)?;
let settings = Settings { pages, paper: PAPERS[0].1, layout: Layout::multiple(4), ..Default::default() };
let sheets = layout(&display_sizes, &settings)?; // geometry only (previews)
let pdf = impose(&doc, &settings)?; // the print-ready PDF
spool::submit(&pdf, &spool::Job { printer: None, copies: 2, ..Default::default() })?;
- Size: fit (to the sheet minus an 18 pt margin), actual size, shrink oversized, custom %; centred; auto orientation turns the sheet for landscape pages.
- Multiple: 2/4/6/9/16 (or any n) pages per sheet, horizontal/vertical (reversed) order,
page borders, auto-rotation of pages that don't match the cell. With auto orientation a
predefined count turns the sheet to suit its grid (2 per sheet prints side by side on
landscape). A custom grid (
Layout::grid,doc_printcols/rows, 1-99 each) is laid out across and down the sheet as given and doesn't turn it: auto prints portrait. - Cut and stack (Multiple's page order): consecutive pages in each cell's pile,
with aligned cut marks in the gutters. For example, 10 pages at 4 per sheet give
[1, 4, 7, 10],[2, 5, 8, blank],[3, 6, 9, blank]. Print single-sided, keep sheets in output order, cut at the marks, then stack the cell piles from left to right, top to bottom. Blank cells can be discarded. Page ranges and Reverse pages are applied before imposition. Duplex imposition is not supported. Headless:doc_printwithlayout: "multiple",order: "cut-stack"andper_sheet: 4(or any supported grid size), pluspathorprinter. - Booklet: saddle-stitch imposition padded to a multiple of 4; both sides, front or back only; left or right binding.
- Poster: tile scale, overlap shared by neighbouring tiles, cut marks.
- Comments & forms: document, + markups, + stamps, or form fields only; annotations print only with their Print flag, drawn from their appearance streams (Algorithm 8.1).
- Properties… on CUPS reads the queue's PPD and its current defaults (
lpoptions -l) off the GUI thread, and giveslpoptionsten seconds: a CUPS that has stopped answering leaves the PPD's own defaults in force instead of holding the dialog (#1818;spool::output_withinkills and reaps the command at the deadline). - Remembered choices (#2001): the dialog keeps two-sided (including leaving it to the
printer), grayscale, collate, page sizing (with its custom percent), Comments & forms and a
booklet's binding side across restarts, in the settings file under
printwith the namesdoc_printtakes (names::duplex,names::content,names::size_modeand theirparse_*counterparts are the one vocabulary). The paper is saved by its own setting (#2156). - Each job starts afresh: copies, pages (the choice, the range, odd/even and reverse), the layout with its own options (pages per sheet, order, borders, booklet subset, poster scale, overlap and cut marks) and orientation reset to the defaults each time Print opens, in the same session too; ISO 32000-2 Table 147 initialises them per document when the print dialog opens. Picked thumbnails still open it on Selected pages. The printer picked last carries over within a session (#3537) but is not saved.
Each source page becomes a Form XObject (its content wrapped in q/Q, plus the printable annotations); sheets place them with a clip. The result is a fresh, unencrypted, garbage-collected file (callers check the print permission). Annotation appearances receive unused XObject names, preserving existing page resources even when they use the same naming prefix.
The GUI Print dialog remembers its last selected paper size across application sessions,
including when Print is cancelled. The preference stores a canonical name such as A4;
unrecognized saved values retain the current selection (US Letter on a fresh app).
This change does not alter persistence of other print preferences.
Headless doc_print defaults are unchanged.
spool delegates discovery, driver options, preferences and submission to
craft-print.
PdfCraft retains page selection, imposition, annotations and print-permission checks.
CUPS jobs stream through stdin with fit-to-page=false, and with orientation-requested=4 when
every sheet is landscape (cups_orientation), since CUPS would otherwise shrink a landscape
sheet into portrait paper. On macOS they also carry the job name and owner
(com.apple.print.JobInfo.PMJobName, PMJobOwner) as the system print dialog sends them, which
some vendors' filters need (#5743). Windows renders sheets through
Windows.Data.Pdf and spools them at their physical PDF size with per-page paper and
orientation, zero added margins and hardware-edge clipping. Long-edge and short-edge duplex
use the corresponding Windows binding edges. Random, exclusively created Windows job files
are removed on success and failure. Other targets offer the print-ready PDF instead.
The shared dependency requires Rust 1.95. Transport and native Windows regression tests live in craft-libs; local tests retain composition, facade, engine, automation and UI coverage. The desktop UI discovers printers and submits jobs on workers, so neither operation blocks the dialog; the Windows backend starts without a console window. Physical printer output still needs hardware validation.
In a browser there is no spooler: the app (pdfcraft-ui-egui's web_print) draws the print-ready
PDF's sheets with PdfCraft's renderer and prints them through the browser's print dialog, which
sets copies, two-sided printing and colour. This crate stays free of web APIs.
Not yet: print as image, poster labels, PostScript output, colour conversion for grayscale.
Architectural sheets and scale
The Paper menu and doc_print share Letter, Legal, Tabloid, A3/A4/A5/A6 plus
ARCH A/B/C/D/E1/E, ANSI C/D/E and ISO A0/A1/A2. ARCH D is 24 × 36 inches;
ANSI D is 22 × 34 inches. Dimensions follow the HP DesignJet paper-size table.
Automation accepts short names such as "ARCH D" (case-insensitive) or the full menu label.
For example, doc_print with paper: "ARCH D", layout: "actual",
orientation: "auto" and path: "plan.pdf" writes a print-ready PDF at 100%.
Match page at 100% uses the currently viewed document page to choose a standard sheet (either orientation, within 0.5 pt for rounded metric dimensions), Actual size and Auto orientation. It leaves the selected page range intact. It is disabled for a custom page size with no matching preset. One preset applies to the whole job; this is not per-page paper-source selection.
PDF scale describes the source-to-sheet transform in the previewed print-ready PDF, not measured physical output. Fit reserves an 18 pt margin and can reduce even a matching page. On Windows craft-print sends the sheets as vectors with a PrintTicket for the sheet's exact paper and no scaling (#599's approach), validated by the driver: a job is refused, not shrunk, when the driver lacks the paper or would change it. Verify the driver's paper settings and physical calibration before relying on drawing scale.