From dc1352b9cd4b0169887d5ce79263f909a0c6412c Mon Sep 17 00:00:00 2001 From: Steffen Becker Date: Sun, 28 Jun 2026 12:47:08 +0200 Subject: [PATCH] fix: print raster instead of vector pdf --- CHANGELOG.md | 3 +- src/App.svelte | 32 ++++++++++-- src/lib/export/pdf.ts | 119 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 127 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a2fc79..591ec75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,7 +60,8 @@ **File & export** - ODT export via odf-kit with extensive content.xml / styles.xml post-processing (custom node types, tables with borders, images, fonts and colors); filename derived from the first heading (fallback `document.odt`) - ODT import / open existing file: parses content.xml / styles.xml directly, adopts the file's margins and orientation, and reports graceful-degradation warnings -- PDF export — Raster (pixel-exact copy of the editor with a selectable text layer) and Vector / Print (crisp, fonts embedded, via the browser print dialog) +- PDF export — Raster (pixel-exact copy of the editor with a selectable text layer) and Vector (crisp, fonts embedded, via the browser print dialog) +- Print (printer button / Ctrl+P) — opens the browser print dialog with a pixel-exact raster of the document (tables, headers/footers and page breaks intact) ### Not yet implemented diff --git a/src/App.svelte b/src/App.svelte index 9d692d9..c6c3f3b 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -7,7 +7,7 @@ import ToolbarExpanded from './lib/components/ToolbarExpanded.svelte'; import FindReplaceBar from './lib/components/FindReplaceBar.svelte'; import { buildOdt, deriveFilename } from './lib/export/odt'; - import { exportPdf, printPdf } from './lib/export/pdf'; + import { exportPdf, printPdf, printRaster } from './lib/export/pdf'; import { supportsFsAccess, saveOdt, saveAsOdt, openOdt } from './lib/export/saveFile'; import { importOdt } from './lib/import/odt'; import { getPageBreakDebug } from './lib/editor/extensions/pageBreaks'; @@ -411,6 +411,30 @@ } } + // Print via the browser's print dialog using the exact raster of the editor (tables, + // header/footer, band masks intact) — print or "Save as PDF". Used by the printer + // button and Ctrl+P, since the vector path re-paginates and mangles tables. + async function handlePrint() { + if (!editor || pdfBusy) return; + exportMenuOpen = false; + pdfBusy = true; + try { + const json = editor.getJSON() as Parameters[0]; + await printRaster({ + source: editor.view.dom as HTMLElement, + json, + fileName: suggestedFilename(json), + orientation: pageOrientation, + numPages, + }); + } catch (err) { + console.error('[pdf] Print failed:', err); + alert('Could not print.'); + } finally { + pdfBusy = false; + } + } + // Vector PDF via the browser's print dialog: crisp, tiny, fonts embedded. Tables // break natively; header/footer become CSS @page boxes (basic text + page numbers). function handlePrintPdf() { @@ -458,7 +482,7 @@ // Ctrl/Cmd+P → Print the paginated document (not the whole app UI). if ((e.ctrlKey || e.metaKey) && !e.shiftKey && (e.key === 'p' || e.key === 'P')) { e.preventDefault(); - handlePrintPdf(); + handlePrint(); } // Ctrl/Cmd+F → Find, Ctrl/Cmd+H → Find & Replace (suppress the browser's own find). if ((e.ctrlKey || e.metaKey) && !e.shiftKey && (e.key === 'f' || e.key === 'F')) { @@ -583,12 +607,12 @@ {/if} -