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:
parent
63471bcbbe
commit
81c7f905bc
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user