diff --git a/client_v2/src/lib/labels/migrateV1.test.ts b/client_v2/src/lib/labels/migrateV1.test.ts index 77eca7dd..21258fb7 100644 --- a/client_v2/src/lib/labels/migrateV1.test.ts +++ b/client_v2/src/lib/labels/migrateV1.test.ts @@ -140,6 +140,26 @@ describe('presetToDesign', () => { expect(d.layout.columns).toBeGreaterThanOrEqual(1); }); + it('clamps v1 negative margins so the label matches the paper (#1149)', () => { + // A real preset: -20mm margins with a 1.5mm printer margin on a 62x34 roll. + // Carried over raw, the derived label came out 102x74. + const d = presetToDesign({ + labelSettings: { + printSettings: { + paperSize: 'custom', + customPaperSize: { width: 62, height: 34 }, + columns: 1, + rows: 1, + margin: { top: -20, bottom: -20, left: -20, right: -20 }, + printerMargin: { top: 1.5, bottom: 1.5, left: 1.5, right: 1.5 } + } + } + }); + expect(d.layout.margin).toEqual({ t: 0, b: 0, l: 0, r: 0 }); + expect(d.layout.safe).toEqual({ t: 1.5, b: 1.5, l: 1.5, r: 1.5 }); + expect(d.label).toEqual({ w: 62, h: 34 }); + }); + it('omits the QR element when v1 had the QR turned off', () => { const d = presetToDesign({ labelSettings: { showQRCodeMode: 'no' } }); expect(d.elements.some((e) => e.type === 'qr')).toBe(false); diff --git a/client_v2/src/lib/labels/migrateV1.ts b/client_v2/src/lib/labels/migrateV1.ts index 8ac7d59d..3de77bdb 100644 --- a/client_v2/src/lib/labels/migrateV1.ts +++ b/client_v2/src/lib/labels/migrateV1.ts @@ -133,11 +133,14 @@ function mapLayout(ps: V1PrintSettings): PrintLayout { paper, custom, landscape: false, + // v1 users paired negative margins with a printer margin to pull an oversized + // grid cell back onto a label-sized page. Clamped, the safe-zone alone gives the + // same inset and the label is sized to the paper instead of that cell (#1149). margin: { - t: ps.margin?.top ?? DEFAULT_LAYOUT.margin.t, - b: ps.margin?.bottom ?? DEFAULT_LAYOUT.margin.b, - l: ps.margin?.left ?? DEFAULT_LAYOUT.margin.l, - r: ps.margin?.right ?? DEFAULT_LAYOUT.margin.r + t: Math.max(0, ps.margin?.top ?? DEFAULT_LAYOUT.margin.t), + b: Math.max(0, ps.margin?.bottom ?? DEFAULT_LAYOUT.margin.b), + l: Math.max(0, ps.margin?.left ?? DEFAULT_LAYOUT.margin.l), + r: Math.max(0, ps.margin?.right ?? DEFAULT_LAYOUT.margin.r) }, safe: { t: ps.printerMargin?.top ?? 0, diff --git a/client_v2/src/lib/labels/print.ts b/client_v2/src/lib/labels/print.ts index efe74a22..1c30eebd 100644 --- a/client_v2/src/lib/labels/print.ts +++ b/client_v2/src/lib/labels/print.ts @@ -141,8 +141,10 @@ export async function printLabels({ design, bindings, layout, baseUrl }: PrintJo style.textContent = pageCss(`${design.label.w}mm ${design.label.h}mm`); } else { buildSheetPages(root, items, design, layout); - const page = paperSize(layout); - style.textContent = pageCss(`${page.w}mm ${page.h}mm`); + // `size: auto`, as v1 did. A fixed size makes the browser pick the orientation + // and (in Chromium) hide the picker, and label printer drivers disagree on which + // way round a roll is, so any fixed choice prints rotated for someone (#1149). + style.textContent = pageCss('auto'); } document.body.appendChild(style);