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.
This commit is contained in:
Emilio Cobos Álvarez 2021-03-26 08:51:53 +01:00
parent 63471bcbbe
commit 81c7f905bc
3 changed files with 20 additions and 44 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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;
}