* Text: a word doesn't break after ?, !, } or + (URLs wrap as in PowerPoint)
Unicode line breaking allows a break after ?, !, } and + inside a word,
so a long URL broke after its '?' and after each '+' of a query and left
the rest of the line empty. Measured in PowerPoint 2016 for Windows with
latinLnBrk off (its default), none of them is a break: the word fills the
line and breaks where it no longer fits, as PowerPoint already does after
/ and \ (break_opportunities). The same synthetic slide now wraps line for
line as PowerPoint's PDF does, a Yandex search URL included.
* Text tests: the first line doesn't end at the separator
* Text tests: check the line is full, not that it avoids ending at a separator
* Keep the Unicode break after ?, !, / outside Latin words
The PowerPoint no-break rule only holds inside a word: before an ideograph
(日本!語) or punctuation the Unicode break stays, as CodeRabbit pointed out.
* Only letters and digits continue a word for the no-break rule
AL and AI also hold symbols such as & and ×, so a!&b kept no break after !.
is_word_char now also requires c.is_alphanumeric() (CodeRabbit).
* Test that Latin before CJK and a separator before a space still break
---------
Co-authored-by: Магда М.Г. <mail@mgmagda.ru>
Found while testing crates/engine/src/cmd/format/font.rs:228-231 (highlight), color_param at crates/engine/src/cmd.rs:381
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
What was wrong: animation.add ignored a `path` parameter, so a customPath
animation always got the default straight path of a quarter of the slide
height, and no command could set or change the points of one.
What changed: animation.add, animation.set and animation.options accept `path`
for a motion path: either points [[x, y], ...] in slide points, as offsets from
where the shape sits (converted to the stored slide-fraction path; `closed`
returns to the first point), or the OOXML path string animation.get answers.
At most 1000 points, finite numbers within 1e6 points, and strings of at most
16 KiB made of path commands and numbers are accepted; anything else is
refused before the deck changes, as is `path` on an animation that is not a
motion path. animation.add answers the stored path.
How it was tested: three new tests in cmd/animation.rs: points become the
expected path (add, set with `closed`, back to the default without `path`), a
raw string is kept and animation.options replaces it, and malformed paths are
refused with nothing added. The animation tests pass, and clippy is clean with
-D warnings.
Fixes#1576
What was wrong: the insert_chart tool had no x, y, w or h in its schema, so the
server refused them as unknown arguments, while insert_picture and insert_table
take them. A chart could only be placed at the default box, [144, 81, 672, 378]
on a 960x540 slide, and then had to be moved with a second command.
What changed: insert_chart declares x, y, w and h and folds them into the
engine's `rect` when all four are given, as insert_picture and insert_table do.
Without all four the chart keeps its default place.
How it was tested: insert_chart_takes_a_box failed before the change (the
arguments were refused) and passes after it. It checks the box of the placed
chart, that a partial box leaves the default place, and that an extreme box is
answered without a panic. The rest of the deckcraft-mcp tests pass, and clippy
is clean with -D warnings.
Fixes#1151
What was wrong: when a page failed its CRC the demuxer had already read the
whole page (up to about 64 KiB), then moved on by one byte and tried again.
Nothing was charged for it, and only the scan for the next capture pattern had
a budget, which a candidate that matches "OggS" at the current position never
reaches. A file made of capture patterns 64 bytes apart, each claiming a full
page, made a 1 MB file read about 957 MB and compute a CRC over all of it. The
warnings list also grew with every damaged page, without limit.
What changed: the per-file recovery budget (32 MiB, the scan's existing one) is
now also charged with the length of every page read only to find its CRC wrong.
When it is spent the pages found so far are returned with a warning saying the
rest was not searched. At most 256 warnings are kept, plus one saying the rest
were dropped.
How it was tested: two new tests failed before the fix and pass after it, a
counting ByteSource over 1 MB of dense fake pages (bytes read stay within the
budget; before, 957 MB were read) and 100,000 bad-CRC pages (before, 199,999
warnings). A file of good pages is not charged and has no warnings. The other
ogg tests still pass, and clippy is clean with -D warnings.
Completes the Ogg part of storytold/filmcraft#2794
Found while testing crates/engine/src/cmd/transition.rs:47-54 (slide_indices, via usize_param)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>