A test for all eleven ruler units (points to Ha): the width and height
the dialog shows read back as the frame's size, so OK never resizes it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An imported cross-reference's text is regenerated only when it is exactly what its format
generates for its destination (Document::drop_generated_xref_text, once the destinations are
resolved); "Page 7, revised" is an edit and is kept, as is the text of one whose destination is
gone. The loose in-order match (matches_format) is gone. Page numbers are recognised by the
instance's AssociatedTextVariable (a cross-reference page number variable, or InDesign's name
for it when the file doesn't define it) rather than its Name, and text inside tracked-change
wrappers counts as shown (insertions in, deletions out). Export writes generated text with its
page numbers as the live variable too, so it reads back as generated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgGsJkVe5GYG9qK6VFdECa
On a parent page a running-header variable shows <Name>, as InDesign shows it (it was blank). Text
with no page that isn't on a parent (a frame composition can't place on a page) keeps the
variable's text before and after: frames now record whether they are on a parent spread, and
the composed values are cached by page and parent.
Split from #1232 (parent-page-display), as asked in review.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgGsJkVe5GYG9qK6VFdECa
A click with a frame tool opened the Rectangle dialog in picas whatever
Preferences > Units & Increments or the rulers' unit menus said. It now
shows the width in the horizontal ruler unit and the height in the
vertical one, and reads bare numbers typed in each field the same way.
The properties panel and the control channel open it the same way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
egui still counts a click when the pointer leaves the tool rect; keep the release modifiers when the press started on the slot. The Alt-cycle test now uses 1 ms frames so an Alt-then-plain pair is a real double-click that must not open Polygon Settings.
Ignore primary releases outside this tool button so another widget cannot steer Alt-cycle or suppress dialogs; harden the Alt-click test to clear i.modifiers before release.
egui pairs a plain click with a prior Alt-click as a double-click; remember the previous click's Alt so polygon/transform dialogs only open for two plain clicks.
Introduced a new test function to check Georgian menu label translations and replaced the previous inline implementation with a call to this new function.
The canvas worked out page boundaries itself, pairing pages in list
order and drawing a line between each pair. Pages that don't touch (an
imported spread can keep gaps between them) got a false spine in the
gap, and list order isn't position order for every spread.
Spread::page_seams, next to spine_x, now gives the edges where two of a
spread's pages meet: pages in position order, facing edges that touch,
each seam spanning both pages' heights. The canvas draws exactly those.
Test: page_seams for a facing pair in either list order, three pages
(two seams), a single page (none), a gap (none) and pages of different
heights.
UPDATE_APP (native builds; craft-update is a native-only dependency) carries our 128 px icon and accent (#7bb51c, 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/cmd/export/text_tests.rs
- crates/pdf/src/gradient_inks.rs
tone() decoded a GIF to RGBA and decode_cmyk_tiff() called read_image()
without the header check decode_rgba() runs. Both now call
too_large_to_decode() first. The decoders' own limits (image 512 MiB,
tiff 256 MiB) already refused these files; the guard refuses them from
the header instead.