From 6bb9eb5416d18032fb3bdcbcec6fe8b07b870074 Mon Sep 17 00:00:00 2001 From: Steffen Becker Date: Thu, 3 Sep 2026 01:11:26 +0200 Subject: [PATCH] fix: a page mirrors its margins only where two masters really alternate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit style:page-usage="right" on a single layout is a page that starts on the right, not one half of a book, and swapping its pair drew it 9mm off. It counts as mirrored now only where masterPageHF found the twin it alternates with. The even-page shift is per section and per first/rest page too — a cover or an index between mirrored pages has margins of its own and mirrors nothing. --- src/lib/components/Editor.svelte | 9 +++++++++ src/lib/editor/extensions/pageBreaks.ts | 14 +++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/lib/components/Editor.svelte b/src/lib/components/Editor.svelte index f6fa10f..7fde074 100644 --- a/src/lib/components/Editor.svelte +++ b/src/lib/components/Editor.svelte @@ -290,9 +290,18 @@ import { EMPTY_PAGE_DECOR, type PageDecor } from '../storage/pageDecor'; ].map((g) => g.join('|')).join(','); }); + // How far an even page's blocks move right, per section and per first/rest page: the + // pair a mirrored section swaps. A section whose own margins mirror nothing — a cover + // between mirrored pages — contributes 0, as does its first page where that differs. + let sectionMirror = $derived([ + [pageMargins, pageMargins], + ...extraHfSections.map((s) => [s.marginsFirst ?? s.margins ?? pageMargins, s.margins ?? pageMargins]), + ].map((g) => g.map((m) => (m.mirrored ? Math.round(cmToPx(m.right) - cmToPx(m.left)) : 0)).join('|')).join(',')); + $effect(() => { const s = document.documentElement.style; s.setProperty('--pb-section-inset', sectionInset); + s.setProperty('--pb-section-mirror', sectionMirror); s.setProperty('--pb-section-page', sectionPaper.map((p) => p.h).join(',')); s.setProperty('--pb-paper-width', `${paperWidth}px`); // The grid the last pass laid out, as "fromPage|height" runs, so every consumer diff --git a/src/lib/editor/extensions/pageBreaks.ts b/src/lib/editor/extensions/pageBreaks.ts index 14d5d73..8b7d063 100644 --- a/src/lib/editor/extensions/pageBreaks.ts +++ b/src/lib/editor/extensions/pageBreaks.ts @@ -1162,10 +1162,13 @@ export const PageBreaks = Extension.create({ const h = paper[Math.min(i, paper.length - 1)]; return Number.isFinite(h) && h > 0 ? h : vm.pageHeight; }; - // Mirrored margins (pageMargins.ts): the padding draws the odd page's pair, - // so an even page's blocks move right by the difference between the two. - const mirrorRaw = parseFloat(csRoot.getPropertyValue('--user-margin-mirror')); - const mirror = Number.isFinite(mirrorRaw) ? mirrorRaw : 0; + // Mirrored margins: the padding draws the odd page's pair, so an even page's + // blocks move right by the difference. Per section — a cover between mirrored + // ones has margins of its own and mirrors nothing. + const mirrors = csRoot.getPropertyValue('--pb-section-mirror').split(',') + .map((g) => g.split('|').map(Number)) + .filter((g) => g.length === 2 && g.every(Number.isFinite)); + const mirrorAt = (i: number) => mirrors[Math.min(i, mirrors.length - 1)] ?? [0, 0]; const scale = getScaleFactor(); const leaves = collectLeaves(CONTENT_HEIGHT, scale); @@ -1583,7 +1586,8 @@ export const PageBreaks = Extension.create({ const landedPage = grid.pageAt(leaf.naturalTop + cumulativeShift); if (leaf.sectionStart) sectionStartPages.push(landedPage); const ins = insetAt(sectionIndex); - const mir = landedPage % 2 === 0 ? mirror : 0; + const mir = landedPage % 2 === 0 + ? mirrorAt(sectionIndex)[landedPage === sectionFirstPage ? 0 : 1] : 0; const insLeft = Math.round((landedPage === sectionFirstPage ? ins[0] : ins[2]) + mir); const insRight = Math.round((landedPage === sectionFirstPage ? ins[1] : ins[3]) - mir); if (insLeft || insRight) {