Commit Graph
342 Commits
Author SHA1 Message Date
FredApps fe70ecce73 Print in grayscale prints on a Windows driver with no grey option (#5806) (#6863)
* 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)
2026-11-10 17:31:12 +01:00
BFlat 4ddf52ef90 Merge pull request #6824 from storytold/merge/egui-725a39fc-6699
Bump storytold/egui to 725a39fc (lands #6699)
2026-11-10 19:23:37 +07:00
huppifluppandFredApps 8864903795 M10: Recognize text no longer clips the first and last letters of a line (#5058)
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
2026-11-10 19:23:21 +07:00
bflatastic 3b23494513 Merge remote-tracking branch 'origin/main' into merge/egui-725a39fc-6699 2026-11-10 15:24:11 +07:00
jonathanwxh-cell 8e6db09459 Zeroize key material, KDF buffers, and UI password drafts (#3928) (#4427) 2026-11-10 10:00:01 +07:00
FredApps 5e114c716f Windows printing: craft-print 0e4943cb (winprint 3c978dfc): pages at the printer's resolution, QName tickets, padded integers (#4941) (#6793)
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.
2026-11-10 03:22:11 +01:00
a71b5124bc M10 #5130: resolve Windows printer-default duplex before spooling (#5180)
* 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>
2026-11-10 02:38:14 +01:00
art804andFredApps dff02827fd Print: list printers without asking drivers; ask only about the one picked (#2192) (#3554)
* 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>
2026-11-10 02:17:00 +01:00
Joaquin ArellanoandClaude Opus 5.5 6914607f17 fix(print): M10 — Windows ya no cambia las letras de las fuentes TrueType incrustadas (#3132) (#4098)
* 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>
2026-11-10 01:33:32 +01:00
bflatastic 2ce2d3cf81 Merge main into merge/ui-print-optimize2
# Conflicts:
#	crates/automation/src/redact.rs
#	crates/automation/src/tools.rs
#	crates/print/src/lib.rs
#	crates/render/src/inspect.rs
#	crates/render/src/lib.rs
2026-11-09 20:56:15 +07:00
mtlcl410 ad0fab3339 Merge remote-tracking branch 'upstream/main' into lane4-4474b
# Conflicts:
#	crates/automation/src/tools.rs
#	crates/automation/tests/it/automation.rs
#	crates/ui-egui/tests/it/document_links.rs
2026-11-09 18:52:46 +08:00
mtlcl410 ed6c8afdef Merge remote-tracking branch 'upstream/main' into lane3-2539b 2026-11-09 18:49:37 +08:00
mtlcl410 59eee050c6 M14: the --control file is owner-only on Windows too, and the CLI checks it (#3922) (#3956) 2026-11-09 18:24:39 +08:00
mtlcl410 66a44f529e M2: the content crate's parser is checked against hayro's, operator by operator (#3107, #3108, #3111, #3177) (#3563) 2026-11-09 18:23:26 +08:00
mtlcl410 bd74ecab92 Merge remote-tracking branch 'upstream/main' into lane3-2539b
# Conflicts:
#	crates/redact/src/tests.rs
2026-11-09 18:20:12 +08:00
mtlcl410 bd5db5dc35 M2: a page whose content was cut at the renderer's limits says so (#623) (#2113) 2026-11-09 18:09:37 +08:00
alehelandClaude Opus 5.5 2be21c2e66 chore(deps): bump storytold/egui to 725a39fc
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>
2026-11-09 10:51:30 +01:00
mtlcl410 375398cfac Merge main into fix/link-uri-base-and-quadpoints
crates/render/Cargo.toml and Cargo.lock: pdfcraft-render takes both url (the
/URI /Base resolution) and main's unicode-bidi.
2026-11-09 14:22:00 +08:00
Dylan M. Taylor 25025fa271 Merge pull request #6674 from dotCooCoo/chore/craft-update-1b34eba41
Updates: take craft-update from craft-libs main at 1b34eba41
2026-11-08 23:30:05 -05:00
mtlcl410 2b9829d6f8 Merge upstream/main into fix/redact-metadata-2448 2026-11-09 12:08:16 +08:00
dotCooCoo 7d4d851343 Updates: take craft-update from craft-libs main at 1b34eba41 2026-11-08 19:47:24 -08:00
mtlcl410andClaude Opus 5.5 8957eef644 Merge upstream/main into fix/link-uri-base-and-quadpoints
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
2026-11-09 11:23:54 +08:00
mtlcl410andClaude Opus 5.5 8c142bef2e Merge upstream/main into fix/redact-metadata-2448
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
2026-11-09 10:12:29 +08:00
bflatastic fbff06bd83 Merge main into merge/redact-forms-misc
# Conflicts:
#	crates/engine/src/tests.rs
#	crates/render/src/inspect/tests.rs
#	crates/render/src/text/tests.rs
2026-11-09 09:03:20 +07:00
bflatastic a7bc9c5301 Merge #6620: M5: comments keep their formatting and appearance through XFDF and FDF (comment.import-fdf-xfdf, comment.export-fdf-xfdf)
# Conflicts:
#	crates/xfdf/src/xfdf.rs
2026-11-09 08:21:11 +07:00
bflatastic 45b95e3bd1 Merge #6597: M3: copied and found text keeps combining marks after their letter and right-to-left word breaks between words (view.copy-text, view.find)
# Conflicts:
#	parity/acrobat-features.toml
2026-11-09 08:20:39 +07:00
bflatastic 9e2c8130ad Merge #6561: M1: a file whose last update has no /Prev opens with all its pages and a repair note (core.repair-broken-files)
# Conflicts:
#	parity/acrobat-features.toml
#	vendor/README.md
#	vendor/hayro-syntax/src/pdf.rs
2026-11-09 08:11:01 +07:00
quincy-jc d0b2a32744 perf(optimize): work out pictures on threads and skip needless page reads (#6230) 2026-11-09 08:53:27 +08:00
mtlcl410andClaude Opus 5.5 684928f0a8 Merge upstream/main into feat/copied-text-letter-order
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-09 05:29:50 +08:00
BFlat c07e092ff5 Merge pull request #6637 from storytold/merge/3492-thai-line-breaks
M7: break Thai rows between dictionary words (#3492, merged with main)
2026-11-09 02:25:04 +08:00
mtlcl410andClaude Opus 5.5 b4efe3f78c Merge upstream/main into feat/xfdf-comment-formatting-appearance
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-09 02:23:40 +08:00
mtlcl410 ae7eba8df4 Merge remote-tracking branch 'upstream/main' into lane1-2539
# Conflicts:
#	crates/engine/src/edit/run.rs
2026-11-09 02:21:08 +08:00
mtlcl410 f9f279f85e Merge remote-tracking branch 'upstream/main' into lane6-6561
# Conflicts:
#	Cargo.lock
2026-11-09 02:20:50 +08:00
FredApps 1afbc1254a Merge pull request #6525 from chamber074/fix/redact-nan-quads
redact: treat unusable /QuadPoints as absent in every reader
2026-11-08 19:06:24 +01:00
bflatastic f6831d58ea Merge remote-tracking branch 'origin/main' into merge/3492-thai-line-breaks 2026-11-09 00:15:27 +07:00
BFlat da6ee1e62a Merge pull request #6634 from storytold/merge/1641-web-ocr
OCR in the web build (#1641, merged with main, two fixes)
2026-11-09 01:10:19 +08:00
bflatastic c8248e3b6d Merge #3492: M7: break Thai rows between dictionary words
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.
2026-11-08 23:58:18 +07:00
FredApps 8d4f2db5b1 Merge branch 'main' into fix/redact-nan-quads 2026-11-08 17:51:37 +01:00
skylar taylor-barrick 883ab41bca Merge pull request #6514 from songzhihui/fix/windows-pdf-stream-loading
M10: adopt file-backed Windows printing with approved dependencies and the crash fix
2026-11-08 17:39:19 +01:00
bflatastic 6bc6d80279 Merge remote-tracking branch 'origin/main' into merge/1641-web-ocr 2026-11-08 23:38:03 +07:00
mtlcl410 c837440959 Merge upstream/main into feat/xfdf-comment-formatting-appearance 2026-11-08 23:20:38 +08:00
mtlcl410andClaude Opus 5.5 27614e43d8 Merge upstream/main into fix/redact-metadata-2448
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
2026-11-08 22:54:03 +08:00
mtlcl410andClaude Opus 5.5 d6ffacbd19 Merge upstream/main into fix/update-without-prev-is-refused
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-08 20:50:01 +08:00
FredApps 5e0619d7eb Merge pull request #1977 from vangel76/feat/redact-mark-regex
Redact: mark text by caller-supplied regex (#1886)
2026-11-08 13:30:34 +01:00
FredApps 8287ad0d06 Merge pull request #6289 from Piohrun/fix/partial-content-rewrite
M2.6: never rewrite a content stream from the part before its damage
2026-11-08 13:10:56 +01:00
Zhihui Song 3763f120a3 chore(print): align application lockfile with refreshed Windows loader 2026-11-08 19:07:54 +08:00
mtlcl410andClaude Opus 5.5 a90502f2c9 M5: comments keep their formatting and appearance through XFDF and FDF (comment.import-fdf-xfdf, comment.export-fdf-xfdf)
XFDF export and import carry each comment's formatting as XFDF 3.0
(ISO 19444-1) names it: contents-richtext (/RC), defaultstyle (/DS),
width/style/dashes (/BS, or an older /Border), cloudy style and
intensity (/BE), rotation, justification (/Q), fringe (/RD) on every
type, leaderLength/leaderExtend/leader-offset and the caption
attributes of lines, the caret symbol and redaction overlay text.

A stamp's appearance travels as <appearance>: base 64 of the
DICT/STREAM/ARRAY/NAME/INT/FIXED/BOOL/STRING/NULL XML other tools
write, with stream data in DATA as XFDF 3.0 "Stream encoding" gives it.
Copy and paste carries every comment's appearance. Import keeps an
appearance it can read (never on a redaction mark), records an
unreadable one in Report::skipped and draws the comment instead; it is
bounded at 16 MiB per appearance, 64 MiB per import, 64 levels and
100,000 values.

FDF export keeps /AP with the forms and images it draws (ISO 32000-2
§12.7.8.3.4); FDF import copies those streams into the document, once
when shared, only for comments that land on a page, and no longer
nulls values past 16 levels (a gradient stamp's shading functions sit
deeper).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pq7HyCHD1R3rywQBPCHXZA
2026-11-08 17:43:00 +08:00
bmh129 9121f65564 M10: OCR models load from bytes; recognised lines travel as JSON (ocr.ocr-web)
The web build has no model files: it downloads them. `Ocr::from_bytes`
loads the pair only when each file's SHA-256 matches ATTRIBUTION.toml
(rten's ONNX parser can spin forever on bytes that aren't a model), and
`OcrsRecognizer::from_ocr` wraps the result as an engine that stays
available without files.

The web build's workers send what they read back as JSON:
`lines_to_json` / `lines_from_json` carry each word's box and, when it
has one, its confidence; the reader credits the words to the engine the
worker ran, and refuses anything else (a missing or non-finite number,
too many words) with an error.
2026-11-07 21:35:26 -06:00
Zhihui Song a67877a4bb M10: preserve stable public GDI identity in the refreshed printing graph 2026-11-08 11:06:42 +08:00
Zhihui Song ef1c54d685 M10: refresh the printing dependency graph and its locked sources 2026-11-08 10:41:33 +08:00