* ODT gap 19: a frame offering several picture formats shows one it can read
LibreOffice writes its own .svm metafile before a PNG of the same picture.
WordCraft took the first whatever it was, so the picture was missing, and gone
from the file once the paragraph was written from the model. Take the first
it can read, as the frame's order of preference means.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ODT: a replacement picture before its object is kept (gap 19)
A frame's picture WordCraft can't show was dropped before the object came, so a
save from the model lost the object's replacement. Found by CodeRabbit on this PR.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ODT: a readable picture after an unreadable replacement is shown and kept (gap 19)
With an unreadable replacement first, the readable picture after it was skipped: WordCraft drew a placeholder and a save from the model lost the picture. It is now shown and written after the replacement. A placeholder is still not written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The test asked the global font database for a fallback face before any
layout call, so the pinned fonts could no longer be installed.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Keep upstream's split of layout_para and install the pinned fonts at its
start. Refit the main tests added since (#4250 widow and footnote length,
#4720 chart fallback font) to the pinned test fonts. Merge the two
wordcraft-layout dev-dependency tables.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The hinting test took whatever default font the machine resolved, so its grey-pixel threshold
depended on the system. It now sets Source Sans 3 at 12 pt (4.7 percent fewer grey pixels).
The footnote test's note length was chosen against system fonts and is now the one that fits
the pinned test fonts, which every layout call now installs.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
layout, layout_para, layout_equation and mark_text_width call test_fonts() first in test
builds, so the shared lay helper and everything that goes through them is covered. Tests and
helpers that look up fonts directly (the Times New Roman substitute test, the Symbol bullet
test, the Arabic/Myanmar/Thai face probes and the nbsp fixture) call it themselves. Audited by
running every layout test in its own process with a temporary guard that panicked on any
global font access before the pinned fonts were installed.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The CSV fallback is now only for an absent values field. A null values argument is rejected
before anything is inserted. Null cells inside a valid row still work. Engine and MCP
regressions check that the document and the undo history stay unchanged.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
layout, layout_para, layout_equation and mark_text_width call test_fonts() first in test
builds, so the shared lay helper and everything that goes through them is covered. Tests and
helpers that look up fonts directly (the Times New Roman substitute test, the Symbol bullet
test, the Arabic/Myanmar/Thai face probes and the nbsp fixture) call it themselves. Audited by
running every layout test in its own process with a temporary guard that panicked on any
global font access before the pinned fonts were installed.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The #3642 guard refused a file whose DIFAT lists more FAT sectors than
its sectors need: one FAT sector per sector_len / 4 sectors plus one
spare. Real writers reserve FAT for growth, so a real encrypted
package — a compound file of 78 sectors — lists 4 FAT sectors and was
refused: encrypted .docx files stopped opening with "the DIFAT lists
4 FAT sectors in a file of 78 sectors" (#5109, broken since the guard
landed).
Every FAT sector listed is a sector of the file, and none of them
twice (checked next), so a real file lists no more FAT sectors than
the file has. The refusal bound is now that: more than num_sectors is
either duplicates or names cfb refuses anyway, and the FAT cfb builds
(one sector of entries per listed name) stays within about the file's
own size — the #3642 blowup listed 2048 × 127 names in a ~1 MB file
and is still refused (260,096 > 2,048).
Co-authored-by: Bra1nZ <bra1nz@astraoffice.com>
With the fixed test fonts the paragraph with a widow needs fewer repeats
than the search range started at.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The footnote text length and the paragraph-length search range in these two
tests were chosen against system fonts; with the fixed test fonts the page
breaks fall elsewhere.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #5710: the Print panel lists printers without asking their drivers
On Windows the printer list waited until every printer's driver said
whether it prints on both sides. A networked printer in power save can
hold that query for a long time, so the list stayed empty and Refresh
stayed unavailable. WordCraft never used the answer.
Discovery now uses craft-print's printer_queues, which lists the same
queues and default without asking any driver (storytold/craft-libs#618).
Printing still checks the job's options with the driver. Only the
craft-print pin moves; craft-ui doesn't depend on it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #5710: the docs say what is proven, not that the sleeping printer is fixed
Review: the progress log and gap rows stated the reported outcome as
certain, but the sleeping network printer hasn't been retested. They now
say the driver query is removed and the reported printer awaits retest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #5710: craft-print pin moves to the merge of storytold/craft-libs#618
e653048 is craft-libs main's merge of #618; crates/print is identical
to the reviewed and tested head 81c2488.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #5710: a print job waiting on its driver can be cancelled, and quitting doesn't wait for it
On Windows a print job asks the printer's driver for its capabilities
before it is sent, and a networked printer in power save can hold that
query for a long time. The Print page stayed locked until the driver
answered, and quitting waited for the job before saving preferences
(CodeRabbit on #5732).
Each job now carries a craft-print Cancel token. Cancel printing
(ui.printCancel) stops a job that hasn't started reaching the spooler,
so it is never sent, and frees the Print page with the settings kept;
a job already being sent completes, and the page says to cancel it
from the system's queue. Quitting cancels jobs still waiting and waits
only for jobs already being sent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #5710: quitting cancels every waiting print job before it waits; Cancel asks the active job
Review: quitting cancelled and waited for jobs one by one, so a job left
waiting while an earlier one was being sent could start sending
meanwhile. Every job is now cancelled first, then only those already
being sent are waited for. Cancel printing asked every unfinished job,
so a job that had just been sent could be reported as cancelled and its
receipt lost; it now asks the job being submitted, which answers that it
was already sent.
The tests cover both orders, junk parameters for ui.printCancel, and the
kept printer list and status message.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #5710: craft-print pin moves to storytold/craft-libs#622 for submit_cancellable
85c8ca1 is #622's head (craft-libs main e653048 plus the Cancel token);
it moves to #622's merge on craft-libs main before this merges.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #5710: craft-print pin follows storytold/craft-libs#622 (230d522)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #5710: pin craft-print to merged cancellation fix
* #5710: allow print cancellation after closing the document
* #5710: correct print-cancellation status date
* #5710: clarify when a print job cannot yet be cancelled in the queue
* #5710: isolate Windows print submissions in cancellable helper processes
* #5710: strengthen helper retry and crash-cleanup regressions
* #5710: erase helper inputs before driver work
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>