From 0c5a919b9722c2109975cbffd47b1a23bea1d244 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Thu, 5 Sep 2024 17:05:22 +0200 Subject: [PATCH] Avoid to have a white line around the canvas The canvas must have the same dims as the page in order to avoid to see the page background. --- src/display/display_utils.js | 8 ++++++-- test/unit/ui_utils_spec.js | 14 ++++++++++++++ web/pdf_page_view.js | 31 ++++++++++++++++++++++++++----- web/pdf_viewer.css | 5 +++++ web/ui_utils.js | 13 +++++++++++++ 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/display/display_utils.js b/src/display/display_utils.js index 31fd390234be9..eb27535730e46 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -1103,8 +1103,12 @@ function setLayerDimensions( const w = `var(--scale-factor) * ${pageWidth}px`, h = `var(--scale-factor) * ${pageHeight}px`; - const widthStr = useRound ? `round(${w}, 1px)` : `calc(${w})`, - heightStr = useRound ? `round(${h}, 1px)` : `calc(${h})`; + const widthStr = useRound + ? `round(down, ${w}, var(--scale-round-x))` + : `calc(${w})`, + heightStr = useRound + ? `round(down, ${h}, var(--scale-round-y))` + : `calc(${h})`; if (!mustFlip || viewport.rotation % 180 === 0) { style.width = widthStr; diff --git a/test/unit/ui_utils_spec.js b/test/unit/ui_utils_spec.js index 4935489f7db07..4c6327d27150e 100644 --- a/test/unit/ui_utils_spec.js +++ b/test/unit/ui_utils_spec.js @@ -16,6 +16,7 @@ import { backtrackBeforeAllVisibleElements, binarySearchFirstItem, + calcRound, getPageSizeInches, getVisibleElements, isPortraitOrientation, @@ -627,4 +628,17 @@ describe("ui_utils", function () { }); }); }); + + describe("calcRound", function () { + it("", function () { + if ( + typeof window !== "undefined" && + window.navigator?.userAgent?.includes("Firefox") + ) { + expect(calcRound(1.6)).not.toEqual(1.6); + } else { + expect(calcRound(1.6)).toEqual(1.6); + } + }); + }); }); diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index 3193e3785440e..a02dd167fe2e7 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -33,6 +33,7 @@ import { } from "pdfjs-lib"; import { approximateFraction, + calcRound, DEFAULT_SCALE, floorToDivide, OutputScale, @@ -127,6 +128,10 @@ class PDFPageView { #previousRotation = null; + #scaleRoundX = 1; + + #scaleRoundY = 1; + #renderError = null; #renderingState = RenderingStates.INITIAL; @@ -1036,11 +1041,27 @@ class PDFPageView { const sfx = approximateFraction(outputScale.sx); const sfy = approximateFraction(outputScale.sy); - canvas.width = floorToDivide(width * outputScale.sx, sfx[0]); - canvas.height = floorToDivide(height * outputScale.sy, sfy[0]); - const { style } = canvas; - style.width = floorToDivide(width, sfx[1]) + "px"; - style.height = floorToDivide(height, sfy[1]) + "px"; + const canvasWidth = (canvas.width = floorToDivide( + calcRound(width * outputScale.sx), + sfx[0] + )); + const canvasHeight = (canvas.height = floorToDivide( + calcRound(height * outputScale.sy), + sfy[0] + )); + const pageWidth = floorToDivide(calcRound(width), sfx[1]); + const pageHeight = floorToDivide(calcRound(height), sfy[1]); + outputScale.sx = canvasWidth / pageWidth; + outputScale.sy = canvasHeight / pageHeight; + + if (this.#scaleRoundX !== sfx[1]) { + this.div.style.setProperty("--scale-round-x", `${sfx[1]}px`); + this.#scaleRoundX = sfx[1]; + } + if (this.#scaleRoundY !== sfy[1]) { + this.div.style.setProperty("--scale-round-y", `${sfy[1]}px`); + this.#scaleRoundY = sfy[1]; + } // Add the viewport so it's known what it was originally drawn with. this.#viewportMap.set(canvas, viewport); diff --git a/web/pdf_viewer.css b/web/pdf_viewer.css index d65173b81b7d5..9082cda37534a 100644 --- a/web/pdf_viewer.css +++ b/web/pdf_viewer.css @@ -83,6 +83,8 @@ canvas { margin: 0; display: block; + width: 100%; + height: 100%; &[hidden] { display: none; @@ -101,6 +103,9 @@ } .pdfViewer .page { + --scale-round-x: 1px; + --scale-round-y: 1px; + direction: ltr; width: 816px; height: 1056px; diff --git a/web/ui_utils.js b/web/ui_utils.js index 08455659cf959..8943ded8f3925 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -862,6 +862,18 @@ function toggleExpandedBtn(button, toggle, view = null) { view?.classList.toggle("hidden", !toggle); } +// In Firefox, the css calc function uses f32 precision but the Chrome or Safari +// are using f64 one. So in order to have the same rendering in all browsers, we +// need to use the right precision in order to have correct dimensions. +const calcRound = (function () { + if (typeof document === "undefined") { + return x => x; + } + const e = document.createElement("div"); + e.style.width = "round(down, calc(1.6666666666666665 * 792px), 1px)"; + return e.style.width === "calc(1320px)" ? Math.fround : x => x; +})(); + export { animationStarted, apiPageLayoutToViewerModes, @@ -870,6 +882,7 @@ export { AutoPrintRegExp, backtrackBeforeAllVisibleElements, // only exported for testing binarySearchFirstItem, + calcRound, CursorTool, DEFAULT_SCALE, DEFAULT_SCALE_DELTA,