From 0ee2a352ecd0ab587123918f6d5ea29b5feccf47 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 24 Jul 2023 10:33:08 +0200 Subject: [PATCH] [api-minor] Replace the `useOnlyCssZoom` option with `maxCanvasPixels = 0` instead (PR 16729 follow-up) Given that the `useOnlyCssZoom` option is essentially just a special-case of the `maxCanvasPixels` functionality, we can combine the two options in order to simplify the overall implementation. Note that the `useOnlyCssZoom` functionality was only ever used, by default, in the PDF Viewer for the B2G/FirefoxOS project (which was abandoned years ago). --- examples/mobile-viewer/viewer.js | 4 +- web/app.js | 1 - web/app_options.js | 5 --- web/pdf_page_view.js | 73 +++++++++++++++++--------------- web/pdf_viewer.js | 15 ++++--- 5 files changed, 51 insertions(+), 47 deletions(-) diff --git a/examples/mobile-viewer/viewer.js b/examples/mobile-viewer/viewer.js index 75886e435d039..022320f5a41bc 100644 --- a/examples/mobile-viewer/viewer.js +++ b/examples/mobile-viewer/viewer.js @@ -20,7 +20,7 @@ if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) { alert("Please build the pdfjs-dist library using\n `gulp dist-install`"); } -const USE_ONLY_CSS_ZOOM = true; +const MAX_CANVAS_PIXELS = 0; // CSS-only zooming. const TEXT_LAYER_MODE = 0; // DISABLE const MAX_IMAGE_SIZE = 1024 * 1024; const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/"; @@ -363,7 +363,7 @@ const PDFViewerApplication = { eventBus, linkService, l10n: this.l10n, - useOnlyCssZoom: USE_ONLY_CSS_ZOOM, + maxCanvasPixels: MAX_CANVAS_PIXELS, textLayerMode: TEXT_LAYER_MODE, }); this.pdfViewer = pdfViewer; diff --git a/web/app.js b/web/app.js index 355e36c481ccd..d105b01e3e7af 100644 --- a/web/app.js +++ b/web/app.js @@ -522,7 +522,6 @@ const PDFViewerApplication = { annotationEditorMode, imageResourcesPath: AppOptions.get("imageResourcesPath"), enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"), - useOnlyCssZoom: AppOptions.get("useOnlyCssZoom"), isOffscreenCanvasSupported, maxCanvasPixels: AppOptions.get("maxCanvasPixels"), enablePermissions: AppOptions.get("enablePermissions"), diff --git a/web/app_options.js b/web/app_options.js index b9aa95ea9557a..13de9889854cf 100644 --- a/web/app_options.js +++ b/web/app_options.js @@ -189,11 +189,6 @@ const defaultOptions = { value: 1, kind: OptionKind.VIEWER + OptionKind.PREFERENCE, }, - useOnlyCssZoom: { - /** @type {boolean} */ - value: false, - kind: OptionKind.VIEWER, - }, viewerCssTheme: { /** @type {number} */ value: typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME") ? 2 : 0, diff --git a/web/pdf_page_view.js b/web/pdf_page_view.js index 5626956feb32c..8838422d38454 100644 --- a/web/pdf_page_view.js +++ b/web/pdf_page_view.js @@ -71,13 +71,11 @@ import { XfaLayerBuilder } from "./xfa_layer_builder.js"; * The default value is `AnnotationMode.ENABLE_FORMS`. * @property {string} [imageResourcesPath] - Path for image resources, mainly * for annotation icons. Include trailing slash. - * @property {boolean} [useOnlyCssZoom] - Enables CSS only zooming. The default - * value is `false`. * @property {boolean} [isOffscreenCanvasSupported] - Allows to use an * OffscreenCanvas if needed. * @property {number} [maxCanvasPixels] - The maximum supported canvas size in - * total pixels, i.e. width * height. Use -1 for no limit. The default value - * is 4096 * 4096 (16 mega-pixels). + * total pixels, i.e. width * height. Use `-1` for no limit, or `0` for + * CSS-only zooming. The default value is 4096 * 4096 (16 mega-pixels). * @property {Object} [pageColors] - Overwrites background and foreground colors * with user defined ones in order to improve readability in high contrast * mode. @@ -112,6 +110,8 @@ const DEFAULT_LAYER_PROPERTIES = () => { class PDFPageView { #annotationMode = AnnotationMode.ENABLE_FORMS; + #hasRestrictedScaling = false; + #layerProperties = null; #loadingId = null; @@ -151,15 +151,13 @@ class PDFPageView { this.pdfPageRotate = defaultViewport.rotation; this._optionalContentConfigPromise = options.optionalContentConfigPromise || null; - this.hasRestrictedScaling = false; this.#textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE; this.#annotationMode = options.annotationMode ?? AnnotationMode.ENABLE_FORMS; this.imageResourcesPath = options.imageResourcesPath || ""; - this.useOnlyCssZoom = options.useOnlyCssZoom || false; this.isOffscreenCanvasSupported = options.isOffscreenCanvasSupported ?? true; - this.maxCanvasPixels = options.maxCanvasPixels || MAX_CANVAS_PIXELS; + this.maxCanvasPixels = options.maxCanvasPixels ?? MAX_CANVAS_PIXELS; this.pageColors = options.pageColors || null; this.eventBus = options.eventBus; @@ -171,6 +169,13 @@ class PDFPageView { if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { this._isStandalone = !this.renderingQueue?.hasViewer(); this._container = container; + + if (options.useOnlyCssZoom) { + console.error( + "useOnlyCssZoom was removed, please use `maxCanvasPixels = 0` instead." + ); + this.maxCanvasPixels = 0; + } } this._annotationCanvasMap = null; @@ -586,23 +591,25 @@ class PDFPageView { this._container?.style.setProperty("--scale-factor", this.viewport.scale); } - let isScalingRestricted = false; - if (this.canvas && this.maxCanvasPixels > 0) { - const { width, height } = this.viewport; - const { sx, sy } = this.outputScale; - if ( - ((Math.floor(width) * sx) | 0) * ((Math.floor(height) * sy) | 0) > - this.maxCanvasPixels - ) { - isScalingRestricted = true; + if (this.canvas) { + let onlyCssZoom = false; + if (this.#hasRestrictedScaling) { + if ( + (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) && + this.maxCanvasPixels === 0 + ) { + onlyCssZoom = true; + } else if (this.maxCanvasPixels > 0) { + const { width, height } = this.viewport; + const { sx, sy } = this.outputScale; + onlyCssZoom = + ((Math.floor(width) * sx) | 0) * ((Math.floor(height) * sy) | 0) > + this.maxCanvasPixels; + } } - } - const onlyCssZoom = - this.useOnlyCssZoom || (this.hasRestrictedScaling && isScalingRestricted); - const postponeDrawing = - !onlyCssZoom && drawingDelay >= 0 && drawingDelay < 1000; + const postponeDrawing = + !onlyCssZoom && drawingDelay >= 0 && drawingDelay < 1000; - if (this.canvas) { if (postponeDrawing || onlyCssZoom) { if ( postponeDrawing && @@ -921,25 +928,25 @@ class PDFPageView { const ctx = canvas.getContext("2d", { alpha: false }); const outputScale = (this.outputScale = new OutputScale()); - if (this.useOnlyCssZoom) { - const actualSizeViewport = viewport.clone({ - scale: PixelsPerInch.PDF_TO_CSS_UNITS, - }); + if ( + (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) && + this.maxCanvasPixels === 0 + ) { + const invScale = 1 / this.scale; // Use a scale that makes the canvas have the originally intended size // of the page. - outputScale.sx *= actualSizeViewport.width / width; - outputScale.sy *= actualSizeViewport.height / height; - } - - if (this.maxCanvasPixels > 0) { + outputScale.sx *= invScale; + outputScale.sy *= invScale; + this.#hasRestrictedScaling = true; + } else if (this.maxCanvasPixels > 0) { const pixelsInViewport = width * height; const maxScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport); if (outputScale.sx > maxScale || outputScale.sy > maxScale) { outputScale.sx = maxScale; outputScale.sy = maxScale; - this.hasRestrictedScaling = true; + this.#hasRestrictedScaling = true; } else { - this.hasRestrictedScaling = false; + this.#hasRestrictedScaling = false; } } const sfx = approximateFraction(outputScale.sx); diff --git a/web/pdf_viewer.js b/web/pdf_viewer.js index 6c4f48122202c..ff6fb9f309fa6 100644 --- a/web/pdf_viewer.js +++ b/web/pdf_viewer.js @@ -108,13 +108,11 @@ function isValidAnnotationEditorMode(mode) { * mainly for annotation icons. Include trailing slash. * @property {boolean} [enablePrintAutoRotate] - Enables automatic rotation of * landscape pages upon printing. The default is `false`. - * @property {boolean} [useOnlyCssZoom] - Enables CSS only zooming. The default - * value is `false`. * @property {boolean} [isOffscreenCanvasSupported] - Allows to use an * OffscreenCanvas if needed. * @property {number} [maxCanvasPixels] - The maximum supported canvas size in - * total pixels, i.e. width * height. Use -1 for no limit. The default value - * is 4096 * 4096 (16 mega-pixels). + * total pixels, i.e. width * height. Use `-1` for no limit, or `0` for + * CSS-only zooming. The default value is 4096 * 4096 (16 mega-pixels). * @property {IL10n} [l10n] - Localization service. * @property {boolean} [enablePermissions] - Enables PDF document permissions, * when they exist. The default value is `false`. @@ -274,8 +272,14 @@ class PDFViewer { this.enablePrintAutoRotate = options.enablePrintAutoRotate || false; if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { this.removePageBorders = options.removePageBorders || false; + + if (options.useOnlyCssZoom) { + console.error( + "useOnlyCssZoom was removed, please use `maxCanvasPixels = 0` instead." + ); + options.maxCanvasPixels = 0; + } } - this.useOnlyCssZoom = options.useOnlyCssZoom || false; this.isOffscreenCanvasSupported = options.isOffscreenCanvasSupported ?? true; this.maxCanvasPixels = options.maxCanvasPixels; @@ -894,7 +898,6 @@ class PDFViewer { textLayerMode, annotationMode, imageResourcesPath: this.imageResourcesPath, - useOnlyCssZoom: this.useOnlyCssZoom, isOffscreenCanvasSupported: this.isOffscreenCanvasSupported, maxCanvasPixels: this.maxCanvasPixels, pageColors: this.pageColors,