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.
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>
* #1180: import an InDesign keyboard shortcut set
Edit > Keyboard Shortcuts gets Import InDesign Set..., which reads the
.txt that InDesign's Show Set writes (window.importShortcuts {path|text}).
Matched commands take the set's Default shortcut, or lose theirs when
every occurrence says [none defined]; other commands give up keys the
set takes. The report lists changes, cleared conflicts, and the items
that could not be matched or read. Tool keys stay fixed.
* #1180: read the set file through the checked reader
* #1180: when two items want the same keys, the later one takes them
With Hyphenate Across Column off, a paragraph whose line ending at an
automatic hyphenation point would end a column or frame is re-laid
without that point, so the word moves on whole, as InDesign does. The
points left out are kept per paragraph across re-lays and cleared when an
earlier paragraph is re-laid. On by default, as in InDesign.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The panel shows the nine alignment buttons in InDesign's groups; indent,
spacing and drop cap fields by their icons in two columns, with Space
Between Paragraphs Using Same Style (Ignore or a space); Shading and Border
with the Paragraph Borders and Shading button and colour; and Hyphenate
with Do Not Align / Align to Baseline Grid.
The panel menu follows InDesign's order: composers, Only Align First Line
to Grid, Balance Ragged Lines, Optical Margin Alignment, the paragraph
dialogs (Keep Options…, Drop Caps and Nested Styles… and GREP Styles… now
open for the selected paragraphs), Bullets and Numbering…, Restart/Continue
Numbering, Define Lists… and the paragraph direction.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* IDML: keep column guides that were dragged off centre (#1096)
InDesign records dragged column guides in `MarginPreference ColumnsPositions`,
as pairs of offsets from the margin box's left edge. The importer discarded them
and divided the columns evenly, so a page whose gutter the designer had moved
came back with it in the middle: on a 450 pt margin box, `0 150 170 450` was
read as columns at 215 and 235.
`Columns::positions` already existed, documented as "Custom column positions
(after dragging column guides)", but nothing set it and nothing read it. Now
`Page::column_rects` returns the custom rects when they are set — that one
method is what the canvas guides, snapping, threading and the first frame of a
placed story all go through, so they follow the dragged gutter — the importer
fills it, and the exporter writes the page's real positions instead of
recomputing an even split, so the round trip keeps them.
`layout.marginsAndColumns` clears them when a count or gutter is set, which is
what InDesign's Margins and Columns does. Without that the stale positions would
outrank the new value and the dialog would look broken.
Verified against InDesign-authored IDML rather than assumed, which settled two
things. The attribute is written whether or not anything was dragged — a real
page's values are exactly its even split — so an even set is dropped rather than
marking every imported page custom and freezing its columns; the tolerance for
that comparison only absorbs float noise, about 1e-14 pt on that page. And
`<Guide>` is a `<Page>` child, not a `<Spread>` one, which is where this
importer already looks: the reporter's missing ruler guide was 099fbd2, landed
the day the ticket was filed, not a second bug.
That commit left `lib.rs` still listing guides as ignored on import; corrected.
* IDML: test a ruler guide in a column gutter without facing pages (#1096)
* View: Lock Guides and Lock Column Guides are commands (#1096)
view.lockGuides {on?} (Cmd+Alt+;) sets the Lock Guides UI state the Properties panel and ruler-guide drags use. view.lockColumnGuides {on?} is a document setting, on by default, saved with the document, not an undo step, and read from and written to IDML ColumnGuideLocked. Both are in View > Grids & Guides with checkmarks.
* IDML: custom column positions are validated and round-trip (#1096)
Columns::positions are used only when they are 2 x count finite edges,
ascending from 0 to the margin box width (within 0.01 pt); anything else
is the even split, in Page::column_rects, on IDML import (bounded parse,
checked against the page's margin box) and on IDML export.
Columns::with_gutter_moved moves one gutter's pair of guides between its
neighbours for the coming column-guide command.
ROADMAP: drop four progress-log lines the #1121 merge duplicated and move
its line to the top.
* Layout: Margins and Columns keeps dragged columns unless the count or gutter changes (#1096)
* Layout: autoflow, inserted pages and new parents follow dragged columns (#1096)
* Integration: close#1121's round-trip test beside the ruler-guide test
* View: Lock Column Guides is translated wherever Lock Guides is (#1096)
* View: Lock Column Guides is translated wherever Lock Guides is (#1096)
* Layout: a new margin or page width resets dragged columns (#1096)
* IDML: a page without its own margins checks the default's column positions against its width (#1096)
* Layout: #1121's margin case follows the new-width rule (#1096)
* View: Lock Column Guides is undoable (#1096)
* Layout: dragged columns scale with a new margin or page width (#1096)
* Layout: dragged columns mirror when a page changes side (#1096)
* Layout: the page-width test drags a page whose columns are its own (#1096)
* Selection: drag a column guide to move its gutter (#1096)
* Layout: pages that follow a one-page parent take its dragged columns mirrored (#1096)
* Selection: column-guide drag review fixes (#1096)
* ROADMAP: the progress line lands in one commit after the guide PRs
---------
Co-authored-by: Hamza <mail.hamzanaveed@gmail.com>