Found while testing crates/engine/src/cmd/file.rs:489 (save, with save_bytes at :341-349 and format_for_path at :440)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/cmd/design/master_view.rs:8 (master_view; `master` read via usize_param, `layout` at :14)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/cmd/file.rs:362 (pdf_options) with crates/pdf/src/lib.rs:364-371 (handout_boxes)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Review follow-up (CodeRabbit on #1658):
- Text levels are resolved before the copy's style changes. A master
placeholder's font reference reached the copy's text (body font in an
accent colour for a title) although the original ignores it: text only
takes the shape's or the layout placeholder's font reference.
- Fill, line and effects come from where `resolve::fill`, `resolve::line`
and `resolve::effects` take them: the first shape in the chain with an
explicit value or a style. A layout's (or the slide's own) style no
longer loses to an explicit fill, line or effect on the master. The
copy gets one style whose references each come from the shape that
supplied that property; unused references are neutral.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A placeholder copied or duplicated on a slide became a regular shape by
clearing `ph`, which also dropped everything it inherited from its layout
and master: the title's 44 pt heading font, the body's bullets and indent
levels, autofit and the box. Without `ph` the text fell back to the
presentation's default style (18 pt, no bullets), on Ctrl+V and the
context menu alike.
`resolve::detach_placeholder` makes the inherited box, fill, line,
effects, body properties and every level's text style the shape's own
before `ph` is cleared. Theme references stay references, so the default
paste still follows the destination theme. Copy (so Cut and pasting into
another deck work after the source is gone) and Duplicate use it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/spell.rs:693 (paragraph_words, the `inside` closure)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Found while testing crates/engine/src/cmd/design/slide_background.rs:65 (index via usize_param); write_background at :175
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The shape.fill params doc listed only linear and radial gradients with
stops, angle and kind. The command also takes the rectangular and path
kinds, focus and rotateWithShape. The doc now names them, and a test
checks the doc's gradient keys and kinds against what the command reads.
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