mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-19 14:48:08 +02:00
[api-minor] Limit the maximum canvas width/height, in addition to its total area (bug 1943094)
Browsers not only limit the maximum total canvas area, but additionally also limit their maximum width/height which affects PDF documents with e.g. very tall and narrow pages. To address this we add a new `maxCanvasDim` viewer-option, which in Firefox will use a browser preference, such that both the total canvas area and the width/height will affect when CSS-zooming is used.
This commit is contained in:
parent
5e6cfbe163
commit
9f9de4508c
6 changed files with 68 additions and 13 deletions
|
@ -477,7 +477,8 @@ const PDFViewerApplication = {
|
|||
)
|
||||
: null;
|
||||
|
||||
const enableHWA = AppOptions.get("enableHWA");
|
||||
const enableHWA = AppOptions.get("enableHWA"),
|
||||
maxCanvasDim = AppOptions.get("maxCanvasDim");
|
||||
const pdfViewer = new PDFViewer({
|
||||
container,
|
||||
viewer,
|
||||
|
@ -506,6 +507,7 @@ const PDFViewerApplication = {
|
|||
imageResourcesPath: AppOptions.get("imageResourcesPath"),
|
||||
enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),
|
||||
maxCanvasPixels: AppOptions.get("maxCanvasPixels"),
|
||||
maxCanvasDim,
|
||||
enableDetailCanvas: AppOptions.get("enableDetailCanvas"),
|
||||
enablePermissions: AppOptions.get("enablePermissions"),
|
||||
pageColors,
|
||||
|
@ -527,6 +529,7 @@ const PDFViewerApplication = {
|
|||
eventBus,
|
||||
renderingQueue: pdfRenderingQueue,
|
||||
linkService: pdfLinkService,
|
||||
maxCanvasDim,
|
||||
pageColors,
|
||||
abortSignal,
|
||||
enableHWA,
|
||||
|
|
|
@ -96,6 +96,11 @@ const defaultOptions = {
|
|||
: null,
|
||||
kind: OptionKind.BROWSER,
|
||||
},
|
||||
maxCanvasDim: {
|
||||
/** @type {number} */
|
||||
value: 32767,
|
||||
kind: OptionKind.BROWSER + OptionKind.VIEWER,
|
||||
},
|
||||
nimbusDataStr: {
|
||||
/** @type {string} */
|
||||
value: "",
|
||||
|
|
|
@ -78,12 +78,14 @@ import { XfaLayerBuilder } from "./xfa_layer_builder.js";
|
|||
* @property {number} [maxCanvasPixels] - The maximum supported canvas size in
|
||||
* total pixels, i.e. width * height. Use `-1` for no limit, or `0` for
|
||||
* CSS-only zooming. The default value is 4096 * 8192 (32 mega-pixels).
|
||||
* @property {number} [maxCanvasDim] - The maximum supported canvas dimension,
|
||||
* in either width or height. Use `-1` for no limit.
|
||||
* The default value is 32767.
|
||||
* @property {boolean} [enableDetailCanvas] - When enabled, if the rendered
|
||||
* pages would need a canvas that is larger than `maxCanvasPixels`, it will
|
||||
* draw a second canvas on top of the CSS-zoomed one, that only renders the
|
||||
* part of the page that is close to the viewport. The default value is
|
||||
* `true`.
|
||||
|
||||
* pages would need a canvas that is larger than `maxCanvasPixels` or
|
||||
* `maxCanvasDim`, it will draw a second canvas on top of the CSS-zoomed one,
|
||||
* that only renders the part of the page that is close to the viewport.
|
||||
* The default value is `true`.
|
||||
* @property {Object} [pageColors] - Overwrites background and foreground colors
|
||||
* with user defined ones in order to improve readability in high contrast
|
||||
* mode.
|
||||
|
@ -185,6 +187,7 @@ class PDFPageView extends BasePDFPageView {
|
|||
this.enableDetailCanvas = options.enableDetailCanvas ?? true;
|
||||
this.maxCanvasPixels =
|
||||
options.maxCanvasPixels ?? AppOptions.get("maxCanvasPixels");
|
||||
this.maxCanvasDim = options.maxCanvasDim || AppOptions.get("maxCanvasDim");
|
||||
this.#enableAutoLinking = options.enableAutoLinking || false;
|
||||
|
||||
this.l10n = options.l10n;
|
||||
|
@ -772,9 +775,21 @@ class PDFPageView extends BasePDFPageView {
|
|||
outputScale.sx *= invScale;
|
||||
outputScale.sy *= invScale;
|
||||
this.#needsRestrictedScaling = true;
|
||||
} else if (this.maxCanvasPixels > 0) {
|
||||
const pixelsInViewport = width * height;
|
||||
const maxScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport);
|
||||
} else if (this.maxCanvasPixels > 0 || this.maxCanvasDim !== -1) {
|
||||
let maxAreaScale = Infinity,
|
||||
maxWidthScale = Infinity,
|
||||
maxHeightScale = Infinity;
|
||||
|
||||
if (this.maxCanvasPixels > 0) {
|
||||
const pixelsInViewport = width * height;
|
||||
maxAreaScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport);
|
||||
}
|
||||
if (this.maxCanvasDim !== -1) {
|
||||
maxWidthScale = this.maxCanvasDim / width;
|
||||
maxHeightScale = this.maxCanvasDim / height;
|
||||
}
|
||||
const maxScale = Math.min(maxAreaScale, maxWidthScale, maxHeightScale);
|
||||
|
||||
if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
|
||||
outputScale.sx = maxScale;
|
||||
outputScale.sy = maxScale;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
/** @typedef {import("./pdf_rendering_queue").PDFRenderingQueue} PDFRenderingQueue */
|
||||
|
||||
import { OutputScale, RenderingCancelledException } from "pdfjs-lib";
|
||||
import { AppOptions } from "./app_options.js";
|
||||
import { RenderingStates } from "./ui_utils.js";
|
||||
|
||||
const DRAW_UPSCALE_FACTOR = 2; // See comment in `PDFThumbnailView.draw` below.
|
||||
|
@ -41,6 +42,9 @@ const THUMBNAIL_WIDTH = 98; // px
|
|||
* The default value is `null`.
|
||||
* @property {IPDFLinkService} linkService - The navigation/linking service.
|
||||
* @property {PDFRenderingQueue} renderingQueue - The rendering queue object.
|
||||
* @property {number} [maxCanvasDim] - The maximum supported canvas dimension,
|
||||
* in either width or height. Use `-1` for no limit.
|
||||
* The default value is 32767.
|
||||
* @property {Object} [pageColors] - Overwrites background and foreground colors
|
||||
* with user defined ones in order to improve readability in high contrast
|
||||
* mode.
|
||||
|
@ -93,6 +97,7 @@ class PDFThumbnailView {
|
|||
optionalContentConfigPromise,
|
||||
linkService,
|
||||
renderingQueue,
|
||||
maxCanvasDim,
|
||||
pageColors,
|
||||
enableHWA,
|
||||
}) {
|
||||
|
@ -105,6 +110,7 @@ class PDFThumbnailView {
|
|||
this.viewport = defaultViewport;
|
||||
this.pdfPageRotate = defaultViewport.rotation;
|
||||
this._optionalContentConfigPromise = optionalContentConfigPromise || null;
|
||||
this.maxCanvasDim = maxCanvasDim || AppOptions.get("maxCanvasDim");
|
||||
this.pageColors = pageColors || null;
|
||||
this.enableHWA = enableHWA || false;
|
||||
|
||||
|
@ -363,9 +369,24 @@ class PDFThumbnailView {
|
|||
);
|
||||
return canvas;
|
||||
}
|
||||
const { maxCanvasDim } = this;
|
||||
|
||||
// drawImage does an awful job of rescaling the image, doing it gradually.
|
||||
let reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS;
|
||||
let reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS;
|
||||
|
||||
if (maxCanvasDim !== -1) {
|
||||
const maxWidthScale = maxCanvasDim / reducedWidth,
|
||||
maxHeightScale = maxCanvasDim / reducedHeight;
|
||||
|
||||
if (maxWidthScale < 1) {
|
||||
reducedWidth = maxCanvasDim;
|
||||
reducedHeight = (reducedHeight * maxWidthScale) | 0;
|
||||
} else if (maxHeightScale < 1) {
|
||||
reducedWidth = (reducedWidth * maxHeightScale) | 0;
|
||||
reducedHeight = maxCanvasDim;
|
||||
}
|
||||
}
|
||||
const [reducedImage, reducedImageCtx] = TempImageFactory.getCanvas(
|
||||
reducedWidth,
|
||||
reducedHeight
|
||||
|
|
|
@ -39,6 +39,9 @@ const THUMBNAIL_SELECTED_CLASS = "selected";
|
|||
* @property {EventBus} eventBus - The application event bus.
|
||||
* @property {IPDFLinkService} linkService - The navigation/linking service.
|
||||
* @property {PDFRenderingQueue} renderingQueue - The rendering queue object.
|
||||
* @property {number} [maxCanvasDim] - The maximum supported canvas dimension,
|
||||
* in either width or height. Use `-1` for no limit.
|
||||
* The default value is 32767.
|
||||
* @property {Object} [pageColors] - Overwrites background and foreground colors
|
||||
* with user defined ones in order to improve readability in high contrast
|
||||
* mode.
|
||||
|
@ -60,6 +63,7 @@ class PDFThumbnailViewer {
|
|||
eventBus,
|
||||
linkService,
|
||||
renderingQueue,
|
||||
maxCanvasDim,
|
||||
pageColors,
|
||||
abortSignal,
|
||||
enableHWA,
|
||||
|
@ -68,6 +72,7 @@ class PDFThumbnailViewer {
|
|||
this.eventBus = eventBus;
|
||||
this.linkService = linkService;
|
||||
this.renderingQueue = renderingQueue;
|
||||
this.maxCanvasDim = maxCanvasDim;
|
||||
this.pageColors = pageColors || null;
|
||||
this.enableHWA = enableHWA || false;
|
||||
|
||||
|
@ -209,6 +214,7 @@ class PDFThumbnailViewer {
|
|||
optionalContentConfigPromise,
|
||||
linkService: this.linkService,
|
||||
renderingQueue: this.renderingQueue,
|
||||
maxCanvasDim: this.maxCanvasDim,
|
||||
pageColors: this.pageColors,
|
||||
enableHWA: this.enableHWA,
|
||||
});
|
||||
|
|
|
@ -118,11 +118,14 @@ function isValidAnnotationEditorMode(mode) {
|
|||
* @property {number} [maxCanvasPixels] - The maximum supported canvas size in
|
||||
* total pixels, i.e. width * height. Use `-1` for no limit, or `0` for
|
||||
* CSS-only zooming. The default value is 4096 * 8192 (32 mega-pixels).
|
||||
* @property {number} [maxCanvasDim] - The maximum supported canvas dimension,
|
||||
* in either width or height. Use `-1` for no limit.
|
||||
* The default value is 32767.
|
||||
* @property {boolean} [enableDetailCanvas] - When enabled, if the rendered
|
||||
* pages would need a canvas that is larger than `maxCanvasPixels`, it will
|
||||
* draw a second canvas on top of the CSS-zoomed one, that only renders the
|
||||
* part of the page that is close to the viewport. The default value is
|
||||
* `true`.
|
||||
* pages would need a canvas that is larger than `maxCanvasPixels` or
|
||||
* `maxCanvasDim`, it will draw a second canvas on top of the CSS-zoomed one,
|
||||
* that only renders the part of the page that is close to the viewport.
|
||||
* The default value is `true`.
|
||||
* @property {IL10n} [l10n] - Localization service.
|
||||
* @property {boolean} [enablePermissions] - Enables PDF document permissions,
|
||||
* when they exist. The default value is `false`.
|
||||
|
@ -326,6 +329,7 @@ class PDFViewer {
|
|||
this.removePageBorders = options.removePageBorders || false;
|
||||
}
|
||||
this.maxCanvasPixels = options.maxCanvasPixels;
|
||||
this.maxCanvasDim = options.maxCanvasDim;
|
||||
this.enableDetailCanvas = options.enableDetailCanvas ?? true;
|
||||
this.l10n = options.l10n;
|
||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
||||
|
@ -1001,6 +1005,7 @@ class PDFViewer {
|
|||
annotationMode,
|
||||
imageResourcesPath: this.imageResourcesPath,
|
||||
maxCanvasPixels: this.maxCanvasPixels,
|
||||
maxCanvasDim: this.maxCanvasDim,
|
||||
enableDetailCanvas: this.enableDetailCanvas,
|
||||
pageColors,
|
||||
l10n: this.l10n,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue