Conflicts:
- crates/compose/src/lib.rs: kept main's line placement (line_metrics with first
baseline tops, baseline grid snap) and this branch's leading model and Aki Below
advance. The Hyphenation Zone check uses Composer::single_line(), so the Japanese
single-line composer gets the zone too.
- crates/idml/src/tests.rs: kept both tests at the conflict (composer kinds, text
stroke alignment).
Also resolved:
- crates/idml/src/import.rs: removed the package scan for a Japanese composer and the
drop of [No paragraph style]'s leading model; the import keeps the file's leading
model and the composer kind, and compose applies the model per paragraph.
- crates/idml/src/tests.rs: the default-leading-model test lays out the document and
checks Roman spacing under the non-Japanese composers and the Aki Below spacing
under the Japanese ones; a new test round-trips a Japanese composer document.
A story that ends with a paragraph return has an empty last paragraph. When
it didn't fit, DesignCraft marked the story overset at the end of its text
(Preflight: "Overset text: 0 characters"; the out port turned red).
InDesign doesn't: Montilla Design's Flex Layout file has a caption ending
with a return, fitted to its three lines, and InDesign reports no errors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
InDesign sets a text line when its baseline fits in the frame; the
descenders may hang below the frame's bottom. DesignCraft required the
baseline plus the descent to fit, so a frame sized to a heading's caps
oversets: Zero2Graphic's magazine tutorial draws 2.7682 cm frames for
103 pt headings (control bar, 4:12–5:44), and all three were overset.
The keep-lines IDML fixture's frames are now 236 pt tall, so they hold the
same 19 lines under either rule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Selecting an empty paragraph (a blank line) puts a collapsed caret on its
hidden paragraph mark, the only character on that line. Previously
type.char either deferred the formatting to the next typed character (in
a non-empty story) or dropped it on the floor for composition, so there
was no way to change a blank line's height — matching InDesign's ability
to select the pilcrow and adjust leading.
- engine/cmd/text.rs: recognize an empty paragraph's own caret position
(empty_para_mark) and apply character attributes straight to that
byte's run instead of deferring to typing format.
- compose/lib.rs: an empty paragraph has no glyphs of its own, so resolve
the hidden mark's run (if overridden) for the paragraph's base leading
instead of always falling back to the paragraph's plain default.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add multi-click text selection, pending caret formatting and clipboard support, text-aware colour controls, guide/grid snapping, and frame threading with loaded-port interactions.
Include the layout, drop-cap and IDML updates carried from #83, with safeguards for generated and linked stories, external text references, local IDs, locked frames and atomic colour edits.
Fixes#23.
Co-authored-by: Sean Hammond <sean.hammond@und.edu>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge current main into the text editing and layout work, retaining the original contributor commits. Preserve generated and linked stories, incoming text references, local IDs and locked frames when threading.
Keep pending formatting and text colours consistent, isolate deferred control clipboard input, and handle inherited IDML frame properties with bounded column allocations. Add focused state-preservation and round-trip regressions and correct the socket and swatch test fixtures.
M2; refs #84.
Start options were skipped for a paragraph at the top of a frame. That is
right for Next Page, Next Frame and Next Column (there is nothing to break
away from), but a Next Odd Page paragraph that lands at the top of an even
page stayed there, as did Next Even Page at the top of an odd page, and the
same went for odd and even page break characters. A part or chapter opener
whose previous section ended exactly at the bottom of an odd page therefore
opened on a left-hand page.
Cursor::start_at_top now moves such a paragraph to the next page of the
asked parity, for paragraphs, tables and break characters alike. Other
start options at the top of a frame are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cross-reference index composed its destination stories through
the cache. One with a running header asked for the running-header
index, which composed the story holding the cross-reference, which
asked for the cross-reference index again: the stack overflowed and
the app aborted. Destination stories with a running header are now
composed without it, like those with cross-references already were.
The paragraph composer counted a trailing space (or several) before the
paragraph end or a forced line break in the line's width, so "2 VOOR " in a
frame exactly as wide as "2 VOOR" broke before "VOOR" and the frame went
overset. InDesign lets those spaces hang past the edge. They now add no
width; the line's visible range already left them out.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cycle checks walk based_on with a seen-set over all parents, so a cycle
longer than the drawing depth cap is still found. Snapping lists parent
items through shown_parent_pages instead of recursing, and offers base
items on a parent spread. A base parent's text on a parent spread is
composed for that spread, so page-number markers show its prefix.
Cmd+Shift-click hits what is drawn: it honours Show Parent Items, hidden
and locked layers, the facing-page filter and layer order. IDML import
warns when a parent spread's pages name different bases or their own
spread.