Binds Properties dialog drafts to the vendored edit-session crate (byte-identical to PerchAnton/edit-session@033f7c3a, ledger in vendor/README) and adds replayable UI scenarios. Includes a merge of main and a test covering the clean Properties inspection-tab live refresh.
* macOS: a job that names no paper tray asks for Auto Select (craft-print 1ee01a4c, #3752)
craft-print 1ee01a4c (storytold/craft-libs#232) sends `AP_D_InputSlot=` on macOS for a job whose
options name no tray, as the system Print dialog's Paper Feed: Auto Select does. Without it CUPS
used the PPD's default tray, and a printer whose default tray is empty held every job while CUPS
reported it completed (the Xerox AltaLink in #3752).
- The Print dialog's driver options take the queue's defaults through craft-print's
apply_queue_defaults: option and choice names match as CUPS matches them, and on macOS the
paper tray starts on Auto Select, which is what the job sends.
- The two tests that pin the exact `lp` arguments expect the Auto Select option on macOS.
* Tests: on macOS a CUPS queue on its driver's default tray shows Auto Select (craft-libs#232)
instances_read_the_queue_ppd_and_their_own_defaults and
a_queue_that_never_answers_is_given_up_at_the_deadline expected the PPD's default tray; on macOS
apply_queue_defaults now offers Auto Select first and as the default there, which is what a job
naming no tray sends. Found by running the print tests on hosted macOS.
* Print in grayscale prints on a Windows driver with no grey option (#5806)
Windows refused Print in grayscale ("the printer's driver did not retain the requested
grayscale; nothing was sent") on drivers that list no grey option the ticket can name:
Microsoft Print to PDF, and an HP Photosmart driver whose grey is its own vendor setting.
- On Windows, a grayscale job's copy for the spooler is made grey first with Convert colours
(all pages, comments and form fields, black kept black, pictures re-encoded where they can
be), and the job says so (Job::grey_pages). The driver is still asked for grey where it has
it; one without prints the grey pages instead of refusing them. A copy that can't be read
goes as it is and asks the driver strictly, as before.
- craft-print 970644b7 (storytold/craft-libs#774) adds Job::grey_pages and asks a driver that
lists only psk:Grayscale for that, not psk:Monochrome.
- Both the Print dialog and doc_print go through spooler_copy, which now takes the job.
* craft-print 1146cdc4: craft-libs main with #774 (grey pages) and #773 (the CUPS printer list waits at most 15 s, storytold/pdfcraft#6761)
storytold/craft-libs#761 moves winprint to 3c978dfc: winprint.rs#19 draws each page at the
job's resolution instead of ~96 dpi (#4941, #2676), #12 writes QName ticket values as
prefix:local (#3823), #3 accepts whitespace around integer capabilities (#2430). Only the
craft-print and winprint lock entries move, plus winprint's windows-numerics dependency.
* M10 #5130: resolve Windows printer-default duplex before spooling
* M10 #5130: document printer duplex resolution
* M10 #5130: adopt DocumentDuplex driver fix from craft-print
* M10 #5130: adopt two-sided capability selection fix
* M10 #5130: update documented craft-print revision
* M10 #5130: fall back when Windows duplex defaults cannot be read
* fix(print): satisfy duplex review formatting and refresh shared pin
* Repin craft-print to craft-libs main (#411 and #133 merged); ask only the picked printer's driver for two-sided support
craft-libs b6b8a55b has #411 (DocumentDuplex) and #133 (two_sided(name)). The
Printer default support check now reads that one driver instead of listing
every printer's capabilities at submit time (#2192).
---------
Co-authored-by: robertobulltech <341520377+robertobulltech@users.noreply.github.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
* Print: list printers without asking drivers; ask only about the one picked (#2192)
On Windows, craft-print's printers() reads every driver's capabilities to
report two-sided support. Windows takes about 48 s to give up on a printer
it can't reach, such as a WSD printer on another network, so the Print
dialog waited for each one before it listed anything (#2192).
The dialog now lists printers from craft-print's printer_queues(), which
asks no driver, and asks two_sided() about the printer the user picks, on
a background thread (PdfCraftApp::two_sided_source, set by the desktop app
like printer_source). Each answer is kept for the session, so a printer is
asked about at most once, and one nobody picks is never waited on. The
"doesn't take two-sided settings" note shows once the answer arrives.
The automation printers tool still uses printers(), so it keeps reporting
two_sided.
Needs the craft-libs change that adds craft_print::two_sided.
* Build: take craft-print from storytold/craft-libs#133
Pins craft-print to the head of storytold/craft-libs#133 (b6a3b87), which
adds craft_print::two_sided as one commit on craft-libs main at 5ee809f.
craft-print is otherwise unchanged from 7ee35a9, the rev main pins now; the
other craft-libs crates stay where they are. Fetched through the
storytold/craft-libs URL, so cargo-deny's allow-git is unchanged. To be
replaced by the merge commit once #133 lands.
* Print: run at most four two-sided reads at once
A driver Windows can't reach holds its two-sided read for about 48 s, so
picking printer after printer started a thread for each. At most four now
run at once; past that, the printer picked is asked once a read finishes.
Tests: hanging reads are capped and the picked printer is asked after one
finishes; a list that already says whether a driver takes two-sided
settings is used as it is, with no driver asked.
* Repin craft-print to craft-libs main, where #133 merged (b6b8a55b)
---------
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
* fix(print): M10 — Windows ya no cambia las letras de las fuentes TrueType incrustadas (#3132)
Un subconjunto TrueType incrustado numera sus glifos de nuevo (en el
subconjunto de Arial de ReportLab el espacio es el glifo 11; en la Arial
instalada, el 3). Al imprimir en Windows, Windows.Data.Pdf → Direct2D →
XPS conservaba esos números de glifo pero los dibujaba con la fuente
instalada del mismo nombre: «Revisión» salía como «Wj{nxn» y la «z» en
negrita como «Ä», tanto en las colas Brother como en la impresora Adobe PDF.
La copia que va a la cola de Windows renombra ahora cada programa
TrueType/OpenType incrustado como PdfCraftPrint<n>, en su tabla name
y en el PDF (/BaseFont, /FontName; el subconjunto conserva su etiqueta),
para que ninguna fuente instalada responda a ese nombre. Glifos,
codificaciones y /ToUnicode no cambian. CUPS y Guardar como PDF reciben
el PDF tal cual.
Tests: extremo a extremo con impose (la página se renderiza idéntica
antes y después, y el test falla sin el arreglo), fuentes que comparten
programa, Type 0, reescritura por plataforma de la tabla name y programas
dañados sin pánico. Falta comprobarlo en una impresora física con Windows.
Fixes#3132
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(print): M10 — solo se renombran en el PDF las fuentes cuyo programa se reescribe (#3132)
Si PdfCraft no puede leer o reescribir un programa incrustado (no es un
sfnt, está dañado o pasa de 64 MiB), ahora conserva también su /BaseFont
y su /FontName. Un visor que tampoco pueda cargarlo seguirá eligiendo el
sustituto por el nombre original («Arial») en vez de por PdfCraftPrint<n>.
Si no queda ningún programa reescrito, el PDF va a la cola tal cual.
Lo señaló CodeRabbit en el PR #4098. Test nuevo:
a_program_that_cannot_be_rewritten_keeps_its_name_in_the_pdf_too (falla
con el comportamiento anterior).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(print): M10 — el renombrado de fuentes para Windows decodifica contra un presupuesto total (#3132)
Cada programa ya tenía un tope de 64 MiB, pero un PDF con muchos
programas distintos podía sumar mucho trabajo de descompresión al
imprimir. Ahora todo el renombrado comparte un DecodeBudget de 512 MiB,
el mecanismo que main acaba de introducir en print. Agotado el
presupuesto, los programas que faltan conservan su nombre, igual que uno
ilegible.
Test nuevo: programs_past_the_shared_decode_budget_keep_their_names
(falla si se decodifica sin presupuesto).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(print): M10 — también se renombran los CIDFont escritos dentro de su fuente Type 0 (#3132)
Si /DescendantFonts lleva el CIDFont como diccionario en línea (en el
propio Type 0 o en un objeto array aparte), el recorrido no llegaba a
él. Cuando compartía programa con otra fuente, el programa se renombraba,
pero el Type 0, el CIDFont y su descriptor seguían diciendo «Arial», y
Windows podía volver a cruzarlos con la Arial instalada. Ahora el Type 0
se trata en el mismo recorrido, sin el segundo que hacía type0_names: un
CIDFont en línea apunta su programa, y al renombrar se cambian el Type 0,
el CIDFont y su descriptor en línea.
Lo señaló CodeRabbit en el PR #4098. Test nuevo:
a_cidfont_written_inside_its_type0_font_is_renamed_with_it (falla sin el
arreglo).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(print): M10 — renamed_table ya no copia cada cadena de la tabla name (#3132)
renamed_table copiaba el texto de cada registro antes de comprobar el
tamaño del resultado: una tabla name de menos de 1 MB con 65.535
registros apuntando a una misma cadena de 65.535 bytes reservaba unos
4 GiB, y un fallo de reserva cierra el proceso al imprimir en Windows.
Ahora la tabla se lee entera sin copiar ningún texto (cada registro
guarda el offset y la longitud de origen) y después cada cadena distinta
se guarda una sola vez: los registros que compartían cadena la siguen
compartiendo y el almacén nunca pasa de lo que alcanzan los offsets de
16 bits. Una tabla que declara más registros de los que caben antes de
sus cadenas se rechaza de entrada.
Lo encontró RomanLis91 en el PR #4098. Tests nuevos:
records_that_share_one_string_keep_sharing_it (falla con el código
anterior) y a_name_table_claiming_more_records_than_fit_before_its_strings_is_refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Moves the egui crates from 6d518fc7 to the tip of the fork's
migration/egui-037-20261024 line. It adds two patches:
- E22: the fallback JavaScript highlighter no longer colours
TypeScript-only keywords (storytold/egui#24).
- E23: dragging a Resize corner keeps a direction that isn't
resizable (storytold/egui#25).
The rest is lint and PATCHES.md only. Default fonts are unchanged,
so the egui-icons provenance link only moves to the new rev. The
vendor graph test and vendor/README.md follow the pin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main moved a link's action reading into Inspector::action_target, shared
with bookmarks, and made the link/attachment text budget start with the
outline. Resolution:
- annotations.rs: link() calls action_target and then resolves a URI
target against /URI /Base, spending what the base adds from the same
budget (or keeping the raw address); QuadPoints reading unchanged.
The budget doc comment covers bookmarks, links, quads and attachments.
- core.rs: keeps the branch's uri_base read; the outline goes through
main's budgeted outline_window (the branch's old call is dropped).
- tools.rs: link_list keeps main's "to_page with its zoom" and the
branch's resolved_url / active_areas text.
relative_uri_actions_resolve_against_the_catalog_base re-proven red with
the resolution reverted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
Keeps main's recovery renewal after applying redactions alongside the
combined notification, and reads XMP and rich-text streams with their
/DecodeParms given by reference made direct, as main's stream readers do.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
Brings the Thai word-breaking branch up to date with main. The only conflict was the edit.add-text parity entry: main's evidence and notes (print inks) are kept, with the new Thai test added and the Thai wrapping sentence updated.
Resolve the conflicts in crates/engine/src/lib.rs (keep both the
redaction-identification and user-regex re-exports) and Cargo.lock
(main's, plus the redact dependencies). Drop the branch's copy of the
test helper pdf_of, which main now defines identically. Fix main's
pdfcraft-edit build: rules.rs joins its content streams through
crate::text::joined now that content_streams returns ContentStream.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA