Skip to content

Commit ab8ebc9

Browse files
Merge pull request #19604 from Snuffleupagus/bug-1943094
[api-minor] Limit the maximum canvas width/height, in addition to its total area (bug 1943094)
2 parents 5e6cfbe + 9f9de45 commit ab8ebc9

6 files changed

+68
-13
lines changed

web/app.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,8 @@ const PDFViewerApplication = {
477477
)
478478
: null;
479479

480-
const enableHWA = AppOptions.get("enableHWA");
480+
const enableHWA = AppOptions.get("enableHWA"),
481+
maxCanvasDim = AppOptions.get("maxCanvasDim");
481482
const pdfViewer = new PDFViewer({
482483
container,
483484
viewer,
@@ -506,6 +507,7 @@ const PDFViewerApplication = {
506507
imageResourcesPath: AppOptions.get("imageResourcesPath"),
507508
enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),
508509
maxCanvasPixels: AppOptions.get("maxCanvasPixels"),
510+
maxCanvasDim,
509511
enableDetailCanvas: AppOptions.get("enableDetailCanvas"),
510512
enablePermissions: AppOptions.get("enablePermissions"),
511513
pageColors,
@@ -527,6 +529,7 @@ const PDFViewerApplication = {
527529
eventBus,
528530
renderingQueue: pdfRenderingQueue,
529531
linkService: pdfLinkService,
532+
maxCanvasDim,
530533
pageColors,
531534
abortSignal,
532535
enableHWA,

web/app_options.js

+5
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ const defaultOptions = {
9696
: null,
9797
kind: OptionKind.BROWSER,
9898
},
99+
maxCanvasDim: {
100+
/** @type {number} */
101+
value: 32767,
102+
kind: OptionKind.BROWSER + OptionKind.VIEWER,
103+
},
99104
nimbusDataStr: {
100105
/** @type {string} */
101106
value: "",

web/pdf_page_view.js

+23-8
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,14 @@ import { XfaLayerBuilder } from "./xfa_layer_builder.js";
7878
* @property {number} [maxCanvasPixels] - The maximum supported canvas size in
7979
* total pixels, i.e. width * height. Use `-1` for no limit, or `0` for
8080
* CSS-only zooming. The default value is 4096 * 8192 (32 mega-pixels).
81+
* @property {number} [maxCanvasDim] - The maximum supported canvas dimension,
82+
* in either width or height. Use `-1` for no limit.
83+
* The default value is 32767.
8184
* @property {boolean} [enableDetailCanvas] - When enabled, if the rendered
82-
* pages would need a canvas that is larger than `maxCanvasPixels`, it will
83-
* draw a second canvas on top of the CSS-zoomed one, that only renders the
84-
* part of the page that is close to the viewport. The default value is
85-
* `true`.
86-
85+
* pages would need a canvas that is larger than `maxCanvasPixels` or
86+
* `maxCanvasDim`, it will draw a second canvas on top of the CSS-zoomed one,
87+
* that only renders the part of the page that is close to the viewport.
88+
* The default value is `true`.
8789
* @property {Object} [pageColors] - Overwrites background and foreground colors
8890
* with user defined ones in order to improve readability in high contrast
8991
* mode.
@@ -185,6 +187,7 @@ class PDFPageView extends BasePDFPageView {
185187
this.enableDetailCanvas = options.enableDetailCanvas ?? true;
186188
this.maxCanvasPixels =
187189
options.maxCanvasPixels ?? AppOptions.get("maxCanvasPixels");
190+
this.maxCanvasDim = options.maxCanvasDim || AppOptions.get("maxCanvasDim");
188191
this.#enableAutoLinking = options.enableAutoLinking || false;
189192

190193
this.l10n = options.l10n;
@@ -772,9 +775,21 @@ class PDFPageView extends BasePDFPageView {
772775
outputScale.sx *= invScale;
773776
outputScale.sy *= invScale;
774777
this.#needsRestrictedScaling = true;
775-
} else if (this.maxCanvasPixels > 0) {
776-
const pixelsInViewport = width * height;
777-
const maxScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport);
778+
} else if (this.maxCanvasPixels > 0 || this.maxCanvasDim !== -1) {
779+
let maxAreaScale = Infinity,
780+
maxWidthScale = Infinity,
781+
maxHeightScale = Infinity;
782+
783+
if (this.maxCanvasPixels > 0) {
784+
const pixelsInViewport = width * height;
785+
maxAreaScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport);
786+
}
787+
if (this.maxCanvasDim !== -1) {
788+
maxWidthScale = this.maxCanvasDim / width;
789+
maxHeightScale = this.maxCanvasDim / height;
790+
}
791+
const maxScale = Math.min(maxAreaScale, maxWidthScale, maxHeightScale);
792+
778793
if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
779794
outputScale.sx = maxScale;
780795
outputScale.sy = maxScale;

web/pdf_thumbnail_view.js

+21
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
/** @typedef {import("./pdf_rendering_queue").PDFRenderingQueue} PDFRenderingQueue */
2525

2626
import { OutputScale, RenderingCancelledException } from "pdfjs-lib";
27+
import { AppOptions } from "./app_options.js";
2728
import { RenderingStates } from "./ui_utils.js";
2829

2930
const DRAW_UPSCALE_FACTOR = 2; // See comment in `PDFThumbnailView.draw` below.
@@ -41,6 +42,9 @@ const THUMBNAIL_WIDTH = 98; // px
4142
* The default value is `null`.
4243
* @property {IPDFLinkService} linkService - The navigation/linking service.
4344
* @property {PDFRenderingQueue} renderingQueue - The rendering queue object.
45+
* @property {number} [maxCanvasDim] - The maximum supported canvas dimension,
46+
* in either width or height. Use `-1` for no limit.
47+
* The default value is 32767.
4448
* @property {Object} [pageColors] - Overwrites background and foreground colors
4549
* with user defined ones in order to improve readability in high contrast
4650
* mode.
@@ -93,6 +97,7 @@ class PDFThumbnailView {
9397
optionalContentConfigPromise,
9498
linkService,
9599
renderingQueue,
100+
maxCanvasDim,
96101
pageColors,
97102
enableHWA,
98103
}) {
@@ -105,6 +110,7 @@ class PDFThumbnailView {
105110
this.viewport = defaultViewport;
106111
this.pdfPageRotate = defaultViewport.rotation;
107112
this._optionalContentConfigPromise = optionalContentConfigPromise || null;
113+
this.maxCanvasDim = maxCanvasDim || AppOptions.get("maxCanvasDim");
108114
this.pageColors = pageColors || null;
109115
this.enableHWA = enableHWA || false;
110116

@@ -363,9 +369,24 @@ class PDFThumbnailView {
363369
);
364370
return canvas;
365371
}
372+
const { maxCanvasDim } = this;
373+
366374
// drawImage does an awful job of rescaling the image, doing it gradually.
367375
let reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS;
368376
let reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS;
377+
378+
if (maxCanvasDim !== -1) {
379+
const maxWidthScale = maxCanvasDim / reducedWidth,
380+
maxHeightScale = maxCanvasDim / reducedHeight;
381+
382+
if (maxWidthScale < 1) {
383+
reducedWidth = maxCanvasDim;
384+
reducedHeight = (reducedHeight * maxWidthScale) | 0;
385+
} else if (maxHeightScale < 1) {
386+
reducedWidth = (reducedWidth * maxHeightScale) | 0;
387+
reducedHeight = maxCanvasDim;
388+
}
389+
}
369390
const [reducedImage, reducedImageCtx] = TempImageFactory.getCanvas(
370391
reducedWidth,
371392
reducedHeight

web/pdf_thumbnail_viewer.js

+6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const THUMBNAIL_SELECTED_CLASS = "selected";
3939
* @property {EventBus} eventBus - The application event bus.
4040
* @property {IPDFLinkService} linkService - The navigation/linking service.
4141
* @property {PDFRenderingQueue} renderingQueue - The rendering queue object.
42+
* @property {number} [maxCanvasDim] - The maximum supported canvas dimension,
43+
* in either width or height. Use `-1` for no limit.
44+
* The default value is 32767.
4245
* @property {Object} [pageColors] - Overwrites background and foreground colors
4346
* with user defined ones in order to improve readability in high contrast
4447
* mode.
@@ -60,6 +63,7 @@ class PDFThumbnailViewer {
6063
eventBus,
6164
linkService,
6265
renderingQueue,
66+
maxCanvasDim,
6367
pageColors,
6468
abortSignal,
6569
enableHWA,
@@ -68,6 +72,7 @@ class PDFThumbnailViewer {
6872
this.eventBus = eventBus;
6973
this.linkService = linkService;
7074
this.renderingQueue = renderingQueue;
75+
this.maxCanvasDim = maxCanvasDim;
7176
this.pageColors = pageColors || null;
7277
this.enableHWA = enableHWA || false;
7378

@@ -209,6 +214,7 @@ class PDFThumbnailViewer {
209214
optionalContentConfigPromise,
210215
linkService: this.linkService,
211216
renderingQueue: this.renderingQueue,
217+
maxCanvasDim: this.maxCanvasDim,
212218
pageColors: this.pageColors,
213219
enableHWA: this.enableHWA,
214220
});

web/pdf_viewer.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,14 @@ function isValidAnnotationEditorMode(mode) {
118118
* @property {number} [maxCanvasPixels] - The maximum supported canvas size in
119119
* total pixels, i.e. width * height. Use `-1` for no limit, or `0` for
120120
* CSS-only zooming. The default value is 4096 * 8192 (32 mega-pixels).
121+
* @property {number} [maxCanvasDim] - The maximum supported canvas dimension,
122+
* in either width or height. Use `-1` for no limit.
123+
* The default value is 32767.
121124
* @property {boolean} [enableDetailCanvas] - When enabled, if the rendered
122-
* pages would need a canvas that is larger than `maxCanvasPixels`, it will
123-
* draw a second canvas on top of the CSS-zoomed one, that only renders the
124-
* part of the page that is close to the viewport. The default value is
125-
* `true`.
125+
* pages would need a canvas that is larger than `maxCanvasPixels` or
126+
* `maxCanvasDim`, it will draw a second canvas on top of the CSS-zoomed one,
127+
* that only renders the part of the page that is close to the viewport.
128+
* The default value is `true`.
126129
* @property {IL10n} [l10n] - Localization service.
127130
* @property {boolean} [enablePermissions] - Enables PDF document permissions,
128131
* when they exist. The default value is `false`.
@@ -326,6 +329,7 @@ class PDFViewer {
326329
this.removePageBorders = options.removePageBorders || false;
327330
}
328331
this.maxCanvasPixels = options.maxCanvasPixels;
332+
this.maxCanvasDim = options.maxCanvasDim;
329333
this.enableDetailCanvas = options.enableDetailCanvas ?? true;
330334
this.l10n = options.l10n;
331335
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
@@ -1001,6 +1005,7 @@ class PDFViewer {
10011005
annotationMode,
10021006
imageResourcesPath: this.imageResourcesPath,
10031007
maxCanvasPixels: this.maxCanvasPixels,
1008+
maxCanvasDim: this.maxCanvasDim,
10041009
enableDetailCanvas: this.enableDetailCanvas,
10051010
pageColors,
10061011
l10n: this.l10n,

0 commit comments

Comments
 (0)