From 81c7f905bcbd21f72ddb59455d469c8bc2e8df63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 26 Mar 2021 08:51:53 +0100 Subject: [PATCH] print: Improve rendering of oversized pages. This improves and simplifies #13102 in order to make printing of test-cases like the one in bug 1698414 (where the real page is bigger than the target page) much better, see incoming screenshots. The reason why we need to stop setting .style.width / .style.height is to get the right auto-sizing behavior in both axes. This shouldn't change behavior as long as the print resolution is >= the CSS resolution, which seems like a reasonable assumption. If you try to print with a lower resolution than CSS, then instead of an stretched canvas, you'd get a centered CSS-quality canvas, which seems sensible. This could maybe be fixed with some CSS hackery (some combination of min / max and viewport units perhaps?), but I think it's more trouble than it's worth. --- web/firefox_print_service.js | 7 ------ web/pdf_print_service.js | 42 +++++++++++------------------------- web/viewer.css | 15 +++++++------ 3 files changed, 20 insertions(+), 44 deletions(-) diff --git a/web/firefox_print_service.js b/web/firefox_print_service.js index 54bb2a4a2..b0d6b119f 100644 --- a/web/firefox_print_service.js +++ b/web/firefox_print_service.js @@ -14,7 +14,6 @@ */ import { RenderingCancelledException, shadow } from "pdfjs-lib"; -import { CSS_UNITS } from "./ui_utils.js"; import { PDFPrintServiceFactory } from "./app.js"; // Creates a placeholder with div and canvas with right size for the page. @@ -33,14 +32,8 @@ function composePage( canvas.width = Math.floor(size.width * PRINT_UNITS); canvas.height = Math.floor(size.height * PRINT_UNITS); - // The physical size of the canvas as specified by the PDF document. - canvas.style.width = Math.floor(size.width * CSS_UNITS) + "px"; - canvas.style.height = Math.floor(size.height * CSS_UNITS) + "px"; - const canvasWrapper = document.createElement("div"); canvasWrapper.appendChild(canvas); - canvasWrapper.style.width = canvas.style.width; - canvasWrapper.style.height = canvas.style.height; printContainer.appendChild(canvasWrapper); // A callback for a given page may be executed multiple times for different diff --git a/web/pdf_print_service.js b/web/pdf_print_service.js index 1071d6fa4..e199903dd 100644 --- a/web/pdf_print_service.js +++ b/web/pdf_print_service.js @@ -14,7 +14,6 @@ */ import { PDFPrintServiceFactory, PDFViewerApplication } from "./app.js"; -import { CSS_UNITS } from "./ui_utils.js"; import { viewerCompatibilityParams } from "./viewer_compatibility.js"; let activeService = null; @@ -37,35 +36,23 @@ function renderPage( scratchCanvas.width = Math.floor(size.width * PRINT_UNITS); scratchCanvas.height = Math.floor(size.height * PRINT_UNITS); - // The physical size of the img as specified by the PDF document. - const width = Math.floor(size.width * CSS_UNITS) + "px"; - const height = Math.floor(size.height * CSS_UNITS) + "px"; - const ctx = scratchCanvas.getContext("2d"); ctx.save(); ctx.fillStyle = "rgb(255, 255, 255)"; ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height); ctx.restore(); - return pdfDocument - .getPage(pageNumber) - .then(function (pdfPage) { - const renderContext = { - canvasContext: ctx, - transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], - viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }), - intent: "print", - annotationStorage: pdfDocument.annotationStorage, - optionalContentConfigPromise, - }; - return pdfPage.render(renderContext).promise; - }) - .then(function () { - return { - width, - height, - }; - }); + return pdfDocument.getPage(pageNumber).then(function (pdfPage) { + const renderContext = { + canvasContext: ctx, + transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], + viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }), + intent: "print", + annotationStorage: pdfDocument.annotationStorage, + optionalContentConfigPromise, + }; + return pdfPage.render(renderContext).promise; + }); } function PDFPrintService( @@ -178,12 +165,9 @@ PDFPrintService.prototype = { return new Promise(renderNextPage); }, - useRenderedPage(printItem) { + useRenderedPage() { this.throwIfInactive(); const img = document.createElement("img"); - img.style.width = printItem.width; - img.style.height = printItem.height; - const scratchCanvas = this.scratchCanvas; if ( "toBlob" in scratchCanvas && @@ -198,8 +182,6 @@ PDFPrintService.prototype = { const wrapper = document.createElement("div"); wrapper.appendChild(img); - wrapper.style.width = img.style.width; - wrapper.style.height = img.style.height; this.printContainer.appendChild(wrapper); return new Promise(function (resolve, reject) { diff --git a/web/viewer.css b/web/viewer.css index 97a1a184f..e982b2577 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -1758,16 +1758,13 @@ html[dir="rtl"] #documentPropertiesOverlay .row > * { } /* wrapper around (scaled) print canvas elements */ #printContainer > div { - /* Without the following max-height declaration, Chromium might create extra - * blank pages, even though it shouldn't! */ - max-height: 100%; page-break-after: always; page-break-inside: avoid; - /* If we're smaller than the page, center the canvas horizontally and - * vertically */ - min-height: 100%; - min-width: 100%; + /* The wrapper always cover the whole page. */ + height: 100%; + width: 100%; + display: flex; flex-direction: column; justify-content: center; @@ -1775,6 +1772,10 @@ html[dir="rtl"] #documentPropertiesOverlay .row > * { } #printContainer canvas, #printContainer img { + /* The intrinsic canvas / image size will make sure that we fit the page. */ + max-width: 100%; + max-height: 100%; + direction: ltr; display: block; }