From ea416505b966ab30b6ac0515ba7f3b268c93d3a5 Mon Sep 17 00:00:00 2001 From: hoyla Date: Fri, 13 Mar 2026 16:41:15 +0000 Subject: [PATCH] Render PageViewer canvas at native device resolution for HiDPI displays Multiply the canvas backing store dimensions by window.devicePixelRatio and set explicit CSS width/height to maintain the same logical layout footprint. Apply canvasContext.scale(dpr, dpr) so PDF.js renders at the higher resolution. The logical scale returned in CachedPreview is unchanged, so text overlays (for selection/copy-paste), search highlights, find-in-document highlights, and comment selection geometry are all unaffected. --- frontend/src/js/components/PageViewer/PdfHelpers.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/frontend/src/js/components/PageViewer/PdfHelpers.ts b/frontend/src/js/components/PageViewer/PdfHelpers.ts index 0a49f1a1..f4636fe2 100644 --- a/frontend/src/js/components/PageViewer/PdfHelpers.ts +++ b/frontend/src/js/components/PageViewer/PdfHelpers.ts @@ -84,8 +84,17 @@ const renderPagePreview = async ( const viewport = pdfPage.getViewport({ scale }); - canvas.width = viewport.width; - canvas.height = viewport.height; + // Render at higher resolution on HiDPI displays for sharper text. + // The canvas backing store is multiplied by DPR, but CSS dimensions + // are set to the logical size so the layout footprint is unchanged. + // Critically, `scale` (returned in CachedPreview) stays as the logical + // scale — text overlays and highlight geometry depend on this. + const dpr = window.devicePixelRatio || 1; + canvas.width = Math.floor(viewport.width * dpr); + canvas.height = Math.floor(viewport.height * dpr); + canvas.style.width = `${viewport.width}px`; + canvas.style.height = `${viewport.height}px`; + canvasContext.scale(dpr, dpr); // Render await pdfPage.render({