Skip to content

Commit 07718e8

Browse files
committed
[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.
1 parent 5e6cfbe commit 07718e8

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed

web/app.js

+1
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ const PDFViewerApplication = {
506506
imageResourcesPath: AppOptions.get("imageResourcesPath"),
507507
enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),
508508
maxCanvasPixels: AppOptions.get("maxCanvasPixels"),
509+
maxCanvasDim: AppOptions.get("maxCanvasDim"),
509510
enableDetailCanvas: AppOptions.get("enableDetailCanvas"),
510511
enablePermissions: AppOptions.get("enablePermissions"),
511512
pageColors,

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

+24-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,22 @@ 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+
const { devicePixelRatio = 1 } = window;
789+
maxWidthScale = this.maxCanvasDim / (width * devicePixelRatio);
790+
maxHeightScale = this.maxCanvasDim / (height * devicePixelRatio);
791+
}
792+
const maxScale = Math.min(maxAreaScale, maxWidthScale, maxHeightScale);
793+
778794
if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
779795
outputScale.sx = maxScale;
780796
outputScale.sy = maxScale;

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)