Pin the final egui, winit and shared UI revisions and reconcile current main.
Preserve document-epoch input and screenshot boundaries, host action ordering,
and Windows path regression coverage. Add click/End batch characterization.
Validation: all nine Linux CI stages pass (3230 tests, zero failures); Windows
CI and bounded native editing workflows pass on the same production source.
* EPUB: Split Document in a paragraph style's Export Tagging
* EPUB: Split Document as a document setting (off, one style, or export tags)
The document stores EPUB Export Options › Split Document (DocSettings.epub_split):
off (one content file, the default), a single paragraph style, or the
paragraph styles' Export Tagging › Split Document flags. document.epubSplit sets
it as one undo step; file.exportEpub takes a split that overrides it for one
export. A Style setting follows a renamed style and a deleted style's
replacement. IDML reads and writes EPubExportPreference BreakDocument and
ParagraphStyleName. A split before a list item or preformatted line closes the
open list or block first, so each content file is balanced.
* EPUB Export Options dialog with Split Document before Export EPUB
File › Export EPUB… opens EPUB Export Options, seeded from the document's
Split Document setting: a Split Document checkbox with Single Paragraph Style
(and its style) or Based on Paragraph Style Export Tags. OK stores a changed
setting through document.epubSplit, then continues to the save dialog; Cancel
does nothing. app.exportEpub with a path skips the dialog. Docs and the
progress log describe the setting.
* EPUB: the navigation test exports one content file with Split Document off
* EPUB export from the menu passes its options (cover, split) to the engine
* EPUB: Split Document on a style's EPUB tag map counts when the style says false; a caller's cover: false stays
Preserve contributor commits and adapt optional-content registration and table-cell graphic calls to the current PDF exporter refactors. Keep current-main roadmap corrections.
All nine cargo xtask ci gates passed on tree d0c21f347e: 3209 tests passed, 6 skipped, 16 WASM-safe crates. The exact PR head also passed 118 PDF unit/integration tests. Independent production-export controls: 8 flat/null cases succeeded; 7 unreadable Prev values refused, 4 compatibility controls succeeded; all 12 emitted PDFs pass qpdf.
This PR is independent of the format-v4 pair (#1647/#1671), which remains held for a reproduced parent-placement IDML issue.
* Type: story Optical Margin Alignment with a size, and Ignore Optical Margin (engine, IDML)
A story's Optical Margin Alignment applies to every paragraph except those
with Ignore Optical Margin; hang amounts scale with the story's size.
story.options sets it, type.para and paragraph styles take
ignoreOpticalMargin. IDML imports and exports StoryPreference
OpticalMarginAlignment/OpticalMarginSize and IgnoreEdgeAlignment. The
per-paragraph opticalMargin switch keeps hanging at the text's own size.
Part of #947.
* Type: the Story panel, and Ignore Optical Margin in the Paragraph panel menu and Paragraph Style Options
Window > Type & Tables > Story sets Optical Margin Alignment and its size
for the stories of the text selection or the selected text frames through
story.options, and is disabled without either. type.selectionAttrs
reports the stories' values as storyOptions, null where they differ.
The Paragraph panel menu toggles ignoreOpticalMargin, and Paragraph Style
Options > Indents and Spacing has an Ignore Optical Margin checkbox.
Part of #947.
* ROADMAP: the story Optical Margin Alignment entry names its default and scope
The new command note.convertFromText removes the selected story text
and puts it into a new editorial note whose anchor sits where the text
was. It takes an optional author, and Convert Note to Text puts the text
back. DesignCraft refuses a selection in a table cell, or one that holds
a note, footnote, endnote, anchored object, index marker, text anchor,
cross-reference or table, and leaves the story unchanged. The item
follows New Note in Type › Notes, with translations in the catalogs that
already translate Convert Note to Text.
Keep source defaults and per-frame hidden layers in plain and PDF/X-4 vector exports, including independent repeated placements, booklet output and book merging. Accept usage-application arrays and resource-only groups without a catalog configuration.
Use file-named warnings and all-ON defaults for recoverable default-configuration problems and unsupported base states. Add readable groups omitted from OCGs without discarding their visibility, combine concurrent recovery warnings, and generate missing names only when no frame override needs name matching. Retain errors for contradictory states, unresolved references and ambiguous name overrides.
Cache prepared variants per asset and hidden-name set while replaying recovery warnings through the existing deduplicating channel. Keep original source bytes when every group is visible and named, so reader-repaired cross-reference tables remain usable without an incremental layer update. When hidden groups or generated names require writing, reject an unusable cross-reference table with a file-named damage error and retain the first placement failure.
Cover visibility, recovery, names, independent placements, repaired cross-reference tables and vector output with 46 optional-content integration tests, plus preparation-cache and shared-buffer unit tests.
Integrate current main (d8d78851) without rewriting the contributor's commits, retaining craft-libs 9f75d3dc.
Accept literal null trailer entries while rejecting actual or ambiguous encryption/hybrid markers. Structurally inspect bounded xref/trailer history instead of adopting trailer-looking comments. Preflight all selected source variants before editing/undo; preserve reset-to-defaults. Suppress stale unrewritable canvas overrides rather than revealing source content. Keep conservative all-content crop fallback without overcropping layerless/null stubs.
Validation: cargo xtask ci, all 9 gates passed; 3062 tests passed, 6 skipped; all 16 WASM-safe crates checked. 17 supported variants passed independent qpdf, logical preservation and Poppler pixel checks; 6 unsupported/repair-only cases refused. Direct-harness Claude Opus 5 reviewed the exact main-relative delta with no blocking findings.
No native-format changes or unrelated layer features. Synthetic regression fixtures are generated in test code.
* Anchored objects: Relative to Spine mirrors custom positions on right-hand pages
* Anchored objects: page side from the frame's spread position; footnote cache keyed by page side
The setting was imported and editable but never read: the composer, the
canvas grid and baseline snapping measured the grid from the page top.
BaselineGrid::origin gives the first line on a page (start, plus the
page's top margin for Top Margin), and all three use it. The composition
cache tracks the setting and the pages' top margins.
Also adds a left-to-right facing-pages guard test for mirrored margins
and the right parent page's guides and running head.
* PDF: craft-pdf, krilla and hayro from craft-libs main (input bounds and crash fixes)
* PDF: craft-libs 9f75d3dc, with hayro-cmap from its vendored copy
A string without a translation shows in English, and an empty catalog row
counts as untranslated. Tests keep duplicate-key and placeholder checks and
the lookup, context, plural-caption and right-to-left mechanics; coverage,
stale-key, wording and per-language literal checks are removed.
`cargo xtask i18n-report`, also a `cargo xtask ci` step, runs the ignored
missing_translations_report test and prints the missing strings per language.
A path passes when it lies inside one of the roots of its kind. The roots'
common parent, a sibling named like a root, `..` or a link out of them and
the other kind's roots stay refused; a folder given twice counts once.
Presentation's spreads now count as one jump in the window's history, and
leaving it as a jump back to the view it was entered from, at the place the
view was. Before, the history stayed on the last presented spread while the
view was put back, so Go Back couldn't reach it.
docs/gaps.md: Go Back and Go Forward are two of the missing menu items, 149.
Autoflow (Shift-click, autoflow on Place, text.thread with autoflow) inserted
new pages right after the story's last frame, in front of the document's own
pages. As in InDesign, it now threads one frame per column on each page that
follows, whatever else the page holds, and only then adds pages at the end of
the document. It fills whole pages, so an estimate that stops inside a page
can't leave its later columns out of the thread. Frames it set past the end
of the text are removed again; the pages they were on stay. Smart Text Reflow
of the primary text frame keeps adding pages after the story's last page.
Shrinks gap 26: flowing into the primary text frame of the following pages
is left.
Track text state through graphics saves and drawn forms; exempt invisible text. Report font names and pages in export warnings and validation without embedding or outlining placed fonts.
A paragraph attribute records that the Bulleted or Numbered List button set
the hanging indent; turning the list off takes the indent away only then
(and while it is still as applied), and clears the mark. A paragraph whose
own indents were 18/-18 before the list keeps them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>