Commit Graph
1386 Commits
Author SHA1 Message Date
Brandon Thomas b3ccea8577 Merge pull request #1498
Decoders: set up picture state inside the panic guard
2026-10-30 15:42:29 -04:00
Brandon Thomas e96ae0b6f5 Merge pull request #1466
PDF export: transparent content pixels take the backdrop colour (fixes #1455)
2026-10-30 15:42:29 -04:00
Brandon Thomas 6fa022d50f Merge pull request #1441
Animation state no longer moves layout and master shapes that share an id with a slide shape (fixes #1362)
2026-10-30 15:42:28 -04:00
Brandon Thomas 62b06a0a91 Merge pull request #1226
Fix the editor's media bar ignoring clicks
2026-10-30 15:42:28 -04:00
Brandon Thomas c389f62b33 Merge pull request #1374
Render: skip shapes far larger than any screen instead of aborting (#1165)

# Conflicts:
#	crates/render/src/renderer.rs
2026-10-30 15:42:21 -04:00
Brandon Thomas 6d02e90177 Merge pull request #1453
Reject '+' sign in slide range numbers
2026-10-30 15:42:14 -04:00
Brandon Thomas 52d81a9468 Merge pull request #1538
Reject invalid slide index in design.applyIdea and design.ideas
2026-10-30 15:42:13 -04:00
Brandon Thomas 81ab1bce0d Merge pull request #1537
Reject invalid slide index in animation.clear
2026-10-30 15:42:13 -04:00
Brandon Thomas 3465ed9d47 Merge pull request #1410
Reject invalid slide index in file.export, file.render, slide.colorAt

# Conflicts:
#	crates/engine/src/tests.rs
2026-10-30 15:42:12 -04:00
Brandon Thomas f29b7e7eed Merge pull request #1481
Tests pinning picture.reset, a repeated PNG export and an action button's theme fill

# Conflicts:
#	crates/engine/src/tests.rs
2026-10-30 15:42:11 -04:00
Brandon Thomas 8075b7ecd8 Merge pull request #1480
show.presenter answers {on, window} (part of #298)
2026-10-30 15:42:11 -04:00
Brandon Thomas a37fa65852 Merge pull request #1479
review.compare says which side each change is on; an absent box is not a rotation
2026-10-30 15:42:10 -04:00
Brandon Thomas 21bbb4127d Merge pull request #1478
A group's box follows its children after a command moves or resizes one

# Conflicts:
#	crates/engine/src/tests.rs
2026-10-30 15:42:10 -04:00
Brandon Thomas 36eaa7e051 Merge pull request #1477
Inserts in the master views: insert.dateTime fills the master's date placeholder; answers say a master or layout was edited (part of #298)

# Conflicts:
#	crates/engine/src/tests.rs
2026-10-30 15:41:59 -04:00
Brandon Thomas 932ec7bef6 Merge pull request #1475
table.cellAlign takes a horizontal align
2026-10-30 15:41:42 -04:00
Dylan M. Taylor 505a6f28ac Update prompt shows the app icon and accent color instead of a letter (#1561)
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#f07a1e, its colour in ArtCraft Launcher). The updater, the self-update
helper and craft-update's startup prompt all get them through crate::UPDATE_APP; the
prompt draws the icon, the accent and "by ArtCraft" (craft-update's default developer).

craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).
Clippy fixes for Rust 1.99 in untouched code (same logic):
- crates/engine/src/tools/click.rs
- crates/engine/src/tools/pointer.rs
- crates/metafile/src/emfplus.rs
- crates/model/src/trendline.rs
- crates/pptx/src/read/dml.rs
- xtask/src/layers.rs
2026-10-30 01:28:38 -04:00
NetterSilverandClaude Haiku 5.5 35a9b812fd Reject invalid slide index in design.applyIdea and design.ideas
Found while testing crates/engine/src/cmd/ideas.rs:254 (apply_cmd); same pattern in ideas_cmd :248

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-29 12:19:26 +01:00
NetterSilverandClaude Haiku 5.5 1bdd63dabe Reject invalid slide index in animation.clear
Found while testing crates/engine/src/cmd/animation.rs:342 (clear)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-29 11:27:56 +01:00
Harrison Booth 63b181170c F-19: guard decoder picture setup against panics 2026-10-28 09:56:13 -05:00
Dylan M. Taylor 8c6c72e39f Refactor ui-egui for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor 1a203c4a73 Refactor engine for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor 7f1ebc2a5c Refactor render for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor 8e4d0e6b4c Refactor pptx for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor 3f853db3f6 Refactor av1 for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor d9749fbcc5 Refactor h264 for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor 0e7cd01381 Refactor hevc for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor 9c52950536 Refactor vp9 for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor c58f19f1b5 Refactor opus for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor 4de3a4dc8b Refactor text for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor f441ea93a2 Refactor metafile for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor 6a59eb8cef Refactor model for strict Clippy checks 2026-10-28 06:02:27 +00:00
Dylan M. Taylor e03ff82504 Refactor geom for strict Clippy checks 2026-10-28 06:02:27 +00:00
Zach BerryandClaude Sonnet 5.5 cd5ff01810 [NN6] review.compare treats an absent box like an unrotated, unflipped one
slide.reset drops a placeholder's stored box, and compare called that
"rotated" because None differed from a stored rotation of 0. Absent now
equals 0 for rotation and no flips; a real flip difference reads "flipped".
PowerPoint's Compare reports a rotation only when the angle differs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 21:43:36 -05:00
Zach BerryandClaude Sonnet 5.5 2cad063d1d [MM4] A group's box follows its children after a command moves one
shape.move or shape.setBounds on a group's child left the group's box as it
was, so inspect_slide reported stale bounds. After any edit that changes a
child's box or the child list, the group's box is refitted to the union of its
children (its child space too, so every child keeps its place on the slide).
A group that was itself moved or resized, and SmartArt groups (regenerated
inside their own box), are left alone.

PowerPoint: a group's bounding box always hugs its children; dragging one
child out grows the group, dragging it back shrinks it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 20:38:41 -05:00
Zach BerryandClaude Sonnet 5.5 3356bc071c [SS1] Pin that an inserted action button's fill follows the theme
It already does: insert.actionButton gives the shape the accent1 style with no explicit fill, as
PowerPoint's gallery button has, so a theme change recolours it. No code change; a test pins it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 20:37:48 -05:00
Zach BerryandClaude Sonnet 5.5 0efd6f1b85 [HH12] Pin that exporting a slide again overwrites the PNG
Not a bug: file.export writes the second PNG over the first with the edit in
it. The test pins it (export, edit, export to the same path, files differ).

PowerPoint: Save As / Export to an existing file name replaces the file.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 20:37:48 -05:00
Zach BerryandClaude Sonnet 5.5 1ca71474a2 [JJ3] show.presenter answers {on, window}
The answer was null. Presenter view is its own window beside the show window,
so window is true; the doc says where it appears.

PowerPoint: Presenter View opens in a separate window on the second display
when the show starts (the Use Presenter View option); same here.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 20:34:18 -05:00
Zach BerryandClaude Sonnet 5.5 f58ec39968 [CC3] table.cellAlign takes a horizontal align
align: left|center|right|justify sets every paragraph of the target cells;
anchor stays the vertical alignment and is optional when align is given.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 20:31:46 -05:00
Harrison Booth 8680166081 test(render): the shared shape id also hides a slide shape in the collision test 2026-10-27 19:18:53 -05:00
Zach BerryandClaude Fable 5.1 4c83fb9abe [CCC2] Insert answers say when they edited a master or layout
PowerPoint shows the Slide Master tab while a master or layout is open,
so inserting there is never mistaken for editing a slide. DeckCraft's
insert commands answered the same in both views. Session::execute now
adds editing: {kind, name} (as slide.inspect does) to the answers of
insert.*, shape.insert, shape.freeform, shape.connect and slide.new in
master, layout, handout and notes-master view; answers on slides are
unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-27 18:55:41 -05:00
Zach BerryandClaude Fable 5.1 6a1b8f1e39 [ZZ1] insert.dateTime in the Handout/Notes Master view fills the master's date placeholder
PowerPoint: Header and Footer > Notes and Handouts > Date and time puts a date field in the
date placeholder of the notes and handout masters, and every handout and notes page shows it.
Before, with no text caret the command wrote the current slide's date placeholder (design
.headerFooter) even in those views, so the handout PDF showed nothing. Now it writes the selected
date placeholder, else the master's own, as a field (update) or plain text, answers where:
master, and refuses (changing nothing) when the master has no date placeholder.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-27 18:55:41 -05:00
Harrison Booth d6f532bb0d PDF export: transparent content pixels take the backdrop colour (fixes #1455)
The content raster's fully transparent pixels were RGB 0,0,0. A viewer that
smooths the image blends colour and mask separately, so the black showed as a
grey hairline around white pictures and white-filled shapes.
2026-10-27 18:52:43 -05:00
Harrison Booth f4ca20659c Merge remote-tracking branch 'origin/main' into dc-fix-ids-1362
# Conflicts:
#	crates/render/src/lib.rs
2026-10-27 18:43:17 -05:00
Zach BerryandClaude Sonnet 5.5 48535be970 [JJ1] review.compare says which side each change is on
Each change now carries number (the editor's slide number beside the 0-based
slide) and onlyIn (deck or file; absent for a change in both). Shape details
say (only in the deck) / (only in the file). The docs say review.accept takes
the file's side.

PowerPoint: Compare marks the other file's differences as revisions that
Accept applies and Reject discards, so accepting takes the file's side; kept.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 18:24:31 -05:00
Zach BerryandClaude Sonnet 5.5 7b424a463b [HH9] picture.reset: document and pin what it keeps (frame shape, size, position)
PowerPoint: Reset Picture discards the picture's formatting changes
(corrections, recolor, artistic effect, picture-style effects and outline);
Reset Picture & Size also restores the size. The frame shape set by Change
Shape is not touched. Ours already left the geometry alone (the reported
geometry wipe does not reproduce); effects, outline and crop are picture
formatting that PowerPoint discards too, so they stay reset (declined:
parity). Added the regression test and the command doc.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 18:24:31 -05:00
aiongg 88c2ceff5f Merge pull request #1461 from Silvertree2010/perf/export-speed
Speed up PDF export by reusing equal slide backdrops
2026-10-27 13:42:02 -04:00
NetterSilverandClaude Opus 5.5 2f4a6d906a Speed up PDF export by reusing equal slide backdrops
PDF export rasterises every slide as a backdrop and a content layer and
hands both to the writer. Profiling (gdb stack sampling) showed most of
the main thread outside rendering going to per-pixel work on those
rasters: compositing the backdrop onto white (not vectorised), the
writer hashing every backdrop to deduplicate it, and the straight-alpha
conversion scanning every content pixel.

- Composite the backdrop with saturating adds and skip 16-pixel blocks
  that are already opaque; skip blocks with no partly transparent pixel
  in the straight-alpha conversion. Same formulas, same bytes.
- Keep the last opaque backdrops (up to 32 MiB of pixels) and hand the
  writer the same image again when a slide renders an identical
  backdrop. The writer stored equal backdrops once already; now it also
  skips hashing and compressing the copies. Output is byte-identical.

deckcraft-cli bench, export .pdf step, 15 interleaved runs each on a
16-thread Ryzen (A/A noise +0.9 %):
- sample x4 (32 slides): median 531 -> 322 ms (-39 %), min 529 -> 317 ms
- same deck, every slide a different background: 557 -> 441 ms (-21 %)
- sample (8 slides): 149 -> 103 ms (-31 %)
Exported PDFs are byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:39:31 +01:00
aiongg 2c9edcc394 refactor(ui): use craft-ui's ComboBox for every dropdown (#1457)
* ui: use craft_ui::ComboBox so dropdown menus grow back (egui#5225); repin craft-libs

* chore(deps): craft-libs 60d60d48 (dropdown fixes)

* chore(deps): craft-libs 6af63481 (dropdown fixes)

* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)

* chore(deps): craft-libs 92d392cf (#387 merged)

* chore(xtask): pdf-deps expects craft-libs 92d392cf
2026-10-27 10:26:51 -04:00
NaseqandClaude Opus 5.5 b1645b006e Render: skip shapes whose outline is not finite or far larger than any screen (#1165)
An ellipse at the EMU limit, compounding group scales or custom-geometry
guides could reach vello's flattener with an outline billions of pixels
long; it sizes its buffer by that length and the allocation aborts the
process. geometry::drawable() rejects a shape with a non-finite path
point, then measures the outline's control box (which always holds the
curve, unlike the tight bounding box when its extremum overflows) unioned
with the frame; past 1e7 device pixels the shape is skipped with a warning.

Rebased onto the render module split: the guard now lives in geometry.rs
and renderer.rs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:12:07 +04:30
NetterSilverandClaude Haiku 5.5 cd2e780432 Reject '+' sign in slide range numbers
Found while testing crates/engine/src/cmd/file.rs:390-400 (parse_slide_range)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 09:19:49 +01:00