From f7b1da418fa6d3d900bef829bf3ddf370e8ac742 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 23 Nov 2021 13:29:00 +0100 Subject: [PATCH] Center pages vertically in PresentationMode (issue 10906) *This patch can be tested e.g. with the `sizes.pdf` document in the test-suite.* While this patch isn't necessarily the best solution, e.g. it might be possible to solve this with *only* CSS, it's what I was able to come up with to address an old issue. The solution here re-uses the `spread`-class in PresentationMode, since that one already takes care of centering pages *vertically*, together with a dummy-page that takes up the entire height of the window. Finally, some PresentationMode-related CSS-rules are also simplified slightly, since the changes in PR 14112 (using Page-scrolling) allows some clean-up here. --- web/base_viewer.js | 64 +++++++++++++++++++++++++++++++++------------- web/pdf_viewer.css | 29 ++++++++++----------- web/viewer.css | 1 - 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/web/base_viewer.js b/web/base_viewer.js index 074447bed..cd78a11a2 100644 --- a/web/base_viewer.js +++ b/web/base_viewer.js @@ -159,24 +159,14 @@ class PDFPageViewBuffer { } } -function isSameScale(oldScale, newScale) { - if (newScale === oldScale) { - return true; - } - if (Math.abs(newScale - oldScale) < 1e-15) { - // Prevent unnecessary re-rendering of all pages when the scale - // changes only because of limited numerical precision. - return true; - } - return false; -} - /** * Simple viewer control to display PDF content/pages. */ class BaseViewer { #buffer = null; + #previousContainerHeight = 0; + #scrollModePageState = null; /** @@ -751,7 +741,20 @@ class BaseViewer { if (this._spreadMode === SpreadMode.NONE) { // Finally, append the new page to the viewer. const pageView = this._pages[pageNumber - 1]; - viewer.appendChild(pageView.div); + + if (this.isInPresentationMode) { + const spread = document.createElement("div"); + spread.className = "spread"; + const dummyPage = document.createElement("div"); + dummyPage.className = "dummyPage"; + dummyPage.style.height = `${this.container.clientHeight}px`; + + spread.appendChild(dummyPage); + spread.appendChild(pageView.div); + viewer.appendChild(spread); + } else { + viewer.appendChild(pageView.div); + } state.pages.push(pageView); } else { @@ -828,10 +831,29 @@ class BaseViewer { scrollIntoView(pageDiv, pageSpot); } + /** + * Prevent unnecessary re-rendering of all pages when the scale changes + * only because of limited numerical precision. + */ + #isSameScale(newScale) { + if ( + this.isInPresentationMode && + this.container.clientHeight !== this.#previousContainerHeight + ) { + // Ensure that the current page remains centered vertically if/when + // the window is resized while PresentationMode is active. + return false; + } + return ( + newScale === this._currentScale || + Math.abs(newScale - this._currentScale) < 1e-15 + ); + } + _setScaleUpdatePages(newScale, newValue, noScroll = false, preset = false) { this._currentScaleValue = newValue.toString(); - if (isSameScale(this._currentScale, newScale)) { + if (this.#isSameScale(newScale)) { if (preset) { this.eventBus.dispatch("scalechanging", { source: this, @@ -886,6 +908,8 @@ class BaseViewer { if (this.defaultRenderingQueue) { this.update(); } + + this.#previousContainerHeight = this.container.clientHeight; } /** @@ -911,11 +935,15 @@ class BaseViewer { if (!currentPage) { return; } - const noPadding = this.isInPresentationMode || this.removePageBorders; - let hPadding = noPadding ? 0 : SCROLLBAR_PADDING; - let vPadding = noPadding ? 0 : VERTICAL_PADDING; + let hPadding = SCROLLBAR_PADDING, + vPadding = VERTICAL_PADDING; - if (!noPadding && this._scrollMode === ScrollMode.HORIZONTAL) { + if (this.isInPresentationMode) { + hPadding = vPadding = 4; + } else if (this.removePageBorders) { + hPadding = vPadding = 0; + } + if (this._scrollMode === ScrollMode.HORIZONTAL) { [hPadding, vPadding] = [vPadding, hPadding]; // Swap the padding values. } const pageWidthScale = diff --git a/web/pdf_viewer.css b/web/pdf_viewer.css index 2fea90745..d98a17969 100644 --- a/web/pdf_viewer.css +++ b/web/pdf_viewer.css @@ -17,7 +17,7 @@ @import url(xfa_layer_builder.css); :root { - --pdfViewer-padding-bottom: none; + --pdfViewer-padding-bottom: 0; --page-margin: 1px auto -8px; --page-border: 9px solid transparent; --spreadHorizontalWrapped-margin-LR: -3.5px; @@ -55,6 +55,12 @@ background-color: rgba(255, 255, 255, 1); } +.pdfViewer .dummyPage { + position: relative; + width: 0; + /* The height is set via JS, see `BaseViewer.#ensurePageViewVisible`. */ +} + .pdfViewer.removePageBorders .page { margin: 0 auto 10px; border: none; @@ -90,6 +96,7 @@ } .spread .page, +.spread .dummyPage, .pdfViewer.scrollHorizontal .page, .pdfViewer.scrollWrapped .page, .pdfViewer.scrollHorizontal .spread, @@ -135,22 +142,14 @@ } .pdfPresentationMode .pdfViewer { - margin-left: 0; - margin-right: 0; + padding-bottom: 0; } -.pdfPresentationMode .pdfViewer .page, -.pdfPresentationMode .pdfViewer .spread { - display: block; +.pdfPresentationMode .spread { + margin: 0; } -.pdfPresentationMode .pdfViewer .page, -.pdfPresentationMode .pdfViewer.removePageBorders .page { - margin-left: auto; - margin-right: auto; -} - -.pdfPresentationMode:fullscreen .pdfViewer .page { - margin-bottom: 100%; - border: 0; +.pdfPresentationMode .pdfViewer .page { + margin: 0 auto; + border: 2px solid transparent; } diff --git a/web/viewer.css b/web/viewer.css index 5850a8763..df33a5054 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -211,7 +211,6 @@ select { #viewerContainer.pdfPresentationMode:fullscreen { top: 0; - border-top: 2px solid rgba(0, 0, 0, 0); background-color: rgba(0, 0, 0, 1); width: 100%; height: 100%;