mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-20 15:18:08 +02:00
[api-minor] Introduce a new annotationMode
-option, in PDFPageProxy.{render, getOperatorList}
*This is a follow-up to PRs 13867 and 13899.* This patch is tagged `api-minor` for the following reasons: - It replaces the `renderInteractiveForms`/`includeAnnotationStorage`-options, in the `PDFPageProxy.render`-method, with the single `annotationMode`-option that controls which annotations are being rendered and how. Note that the old options were mutually exclusive, and setting both to `true` would result in undefined behaviour. - For improved consistency in the API, the `annotationMode`-option will also work together with the `PDFPageProxy.getOperatorList`-method. - It's now also possible to disable *all* annotation rendering in both the API and the Viewer, since the other changes meant that this could now be supported with a single added line on the worker-thread[1]; fixes 7282. --- [1] Please note that in order to simplify the overall implementation, we'll purposely only support disabling of *all* annotations and that the option is being shared between the API and the Viewer. For any more "specialized" use-cases, where e.g. only some annotation-types are being rendered and/or the API and Viewer render different sets of annotations, that'll have to be handled in third-party implementations/forks of the PDF.js code-base.
This commit is contained in:
parent
56e7bb626c
commit
41efa3c071
16 changed files with 272 additions and 134 deletions
|
@ -24,7 +24,7 @@ import { SimpleLinkService } from "./pdf_link_service.js";
|
|||
* @property {AnnotationStorage} [annotationStorage]
|
||||
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||
* for annotation icons. Include trailing slash.
|
||||
* @property {boolean} renderInteractiveForms
|
||||
* @property {boolean} renderForms
|
||||
* @property {IPDFLinkService} linkService
|
||||
* @property {DownloadManager} downloadManager
|
||||
* @property {IL10n} l10n - Localization service.
|
||||
|
@ -44,7 +44,7 @@ class AnnotationLayerBuilder {
|
|||
downloadManager,
|
||||
annotationStorage = null,
|
||||
imageResourcesPath = "",
|
||||
renderInteractiveForms = true,
|
||||
renderForms = true,
|
||||
l10n = NullL10n,
|
||||
enableScripting = false,
|
||||
hasJSActionsPromise = null,
|
||||
|
@ -55,7 +55,7 @@ class AnnotationLayerBuilder {
|
|||
this.linkService = linkService;
|
||||
this.downloadManager = downloadManager;
|
||||
this.imageResourcesPath = imageResourcesPath;
|
||||
this.renderInteractiveForms = renderInteractiveForms;
|
||||
this.renderForms = renderForms;
|
||||
this.l10n = l10n;
|
||||
this.annotationStorage = annotationStorage;
|
||||
this.enableScripting = enableScripting;
|
||||
|
@ -90,7 +90,7 @@ class AnnotationLayerBuilder {
|
|||
annotations,
|
||||
page: this.pdfPage,
|
||||
imageResourcesPath: this.imageResourcesPath,
|
||||
renderInteractiveForms: this.renderInteractiveForms,
|
||||
renderForms: this.renderForms,
|
||||
linkService: this.linkService,
|
||||
downloadManager: this.downloadManager,
|
||||
annotationStorage: this.annotationStorage,
|
||||
|
@ -139,7 +139,7 @@ class DefaultAnnotationLayerFactory {
|
|||
* @param {AnnotationStorage} [annotationStorage]
|
||||
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
||||
* for annotation icons. Include trailing slash.
|
||||
* @param {boolean} renderInteractiveForms
|
||||
* @param {boolean} renderForms
|
||||
* @param {IL10n} l10n
|
||||
* @param {boolean} [enableScripting]
|
||||
* @param {Promise<boolean>} [hasJSActionsPromise]
|
||||
|
@ -151,7 +151,7 @@ class DefaultAnnotationLayerFactory {
|
|||
pdfPage,
|
||||
annotationStorage = null,
|
||||
imageResourcesPath = "",
|
||||
renderInteractiveForms = true,
|
||||
renderForms = true,
|
||||
l10n = NullL10n,
|
||||
enableScripting = false,
|
||||
hasJSActionsPromise = null,
|
||||
|
@ -161,7 +161,7 @@ class DefaultAnnotationLayerFactory {
|
|||
pageDiv,
|
||||
pdfPage,
|
||||
imageResourcesPath,
|
||||
renderInteractiveForms,
|
||||
renderForms,
|
||||
linkService: new SimpleLinkService(),
|
||||
l10n,
|
||||
annotationStorage,
|
||||
|
|
|
@ -515,8 +515,8 @@ const PDFViewerApplication = {
|
|||
renderer: AppOptions.get("renderer"),
|
||||
l10n: this.l10n,
|
||||
textLayerMode: AppOptions.get("textLayerMode"),
|
||||
annotationMode: AppOptions.get("annotationMode"),
|
||||
imageResourcesPath: AppOptions.get("imageResourcesPath"),
|
||||
renderInteractiveForms: AppOptions.get("renderInteractiveForms"),
|
||||
enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),
|
||||
useOnlyCssZoom: AppOptions.get("useOnlyCssZoom"),
|
||||
maxCanvasPixels: AppOptions.get("maxCanvasPixels"),
|
||||
|
@ -1555,7 +1555,7 @@ const PDFViewerApplication = {
|
|||
this.fallback(UNSUPPORTED_FEATURES.forms);
|
||||
} else if (
|
||||
(info.IsAcroFormPresent || info.IsXFAPresent) &&
|
||||
!this.pdfViewer.renderInteractiveForms
|
||||
!this.pdfViewer.renderForms
|
||||
) {
|
||||
console.warn("Warning: Interactive form support is not enabled");
|
||||
this.fallback(UNSUPPORTED_FEATURES.forms);
|
||||
|
|
|
@ -59,6 +59,11 @@ const OptionKind = {
|
|||
* values below *explicitly* rather than relying on imported types.
|
||||
*/
|
||||
const defaultOptions = {
|
||||
annotationMode: {
|
||||
/** @type {number} */
|
||||
value: 2,
|
||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||
},
|
||||
cursorToolOnLoad: {
|
||||
/** @type {number} */
|
||||
value: 0,
|
||||
|
@ -145,11 +150,6 @@ const defaultOptions = {
|
|||
value: "canvas",
|
||||
kind: OptionKind.VIEWER,
|
||||
},
|
||||
renderInteractiveForms: {
|
||||
/** @type {boolean} */
|
||||
value: true,
|
||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||
},
|
||||
sidebarViewOnLoad: {
|
||||
/** @type {number} */
|
||||
value: -1,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createPromiseCapability, version } from "pdfjs-lib";
|
||||
import { AnnotationMode, createPromiseCapability, version } from "pdfjs-lib";
|
||||
import {
|
||||
CSS_UNITS,
|
||||
DEFAULT_SCALE,
|
||||
|
@ -67,10 +67,13 @@ const DEFAULT_CACHE_SIZE = 10;
|
|||
* selection and searching is created, and if the improved text selection
|
||||
* behaviour is enabled. The constants from {TextLayerMode} should be used.
|
||||
* The default value is `TextLayerMode.ENABLE`.
|
||||
* @property {number} [annotationMode] - Controls if the annotation layer is
|
||||
* created, and if interactive form elements or `AnnotationStorage`-data are
|
||||
* being rendered. The constants from {@link AnnotationMode} should be used;
|
||||
* see also {@link RenderParameters} and {@link GetOperatorListParameters}.
|
||||
* The default value is `AnnotationMode.ENABLE_FORMS`.
|
||||
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||
* mainly for annotation icons. Include trailing slash.
|
||||
* @property {boolean} [renderInteractiveForms] - Enables rendering of
|
||||
* interactive form elements. The default value is `true`.
|
||||
* @property {boolean} [enablePrintAutoRotate] - Enables automatic rotation of
|
||||
* landscape pages upon printing. The default is `false`.
|
||||
* @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'.
|
||||
|
@ -182,11 +185,10 @@ class BaseViewer {
|
|||
this.findController = options.findController || null;
|
||||
this._scriptingManager = options.scriptingManager || null;
|
||||
this.removePageBorders = options.removePageBorders || false;
|
||||
this.textLayerMode = Number.isInteger(options.textLayerMode)
|
||||
? options.textLayerMode
|
||||
: TextLayerMode.ENABLE;
|
||||
this.textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE;
|
||||
this._annotationMode =
|
||||
options.annotationMode ?? AnnotationMode.ENABLE_FORMS;
|
||||
this.imageResourcesPath = options.imageResourcesPath || "";
|
||||
this.renderInteractiveForms = options.renderInteractiveForms !== false;
|
||||
this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;
|
||||
this.renderer = options.renderer || RendererType.CANVAS;
|
||||
this.useOnlyCssZoom = options.useOnlyCssZoom || false;
|
||||
|
@ -240,6 +242,13 @@ class BaseViewer {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get renderForms() {
|
||||
return this._annotationMode === AnnotationMode.ENABLE_FORMS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
|
@ -529,6 +538,8 @@ class BaseViewer {
|
|||
this.textLayerMode !== TextLayerMode.DISABLE && !isPureXfa
|
||||
? this
|
||||
: null;
|
||||
const annotationLayerFactory =
|
||||
this._annotationMode !== AnnotationMode.DISABLE ? this : null;
|
||||
const xfaLayerFactory = isPureXfa ? this : null;
|
||||
|
||||
for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
|
||||
|
@ -542,12 +553,12 @@ class BaseViewer {
|
|||
renderingQueue: this.renderingQueue,
|
||||
textLayerFactory,
|
||||
textLayerMode: this.textLayerMode,
|
||||
annotationLayerFactory: this,
|
||||
annotationLayerFactory,
|
||||
annotationMode: this._annotationMode,
|
||||
xfaLayerFactory,
|
||||
textHighlighterFactory: this,
|
||||
structTreeLayerFactory: this,
|
||||
imageResourcesPath: this.imageResourcesPath,
|
||||
renderInteractiveForms: this.renderInteractiveForms,
|
||||
renderer: this.renderer,
|
||||
useOnlyCssZoom: this.useOnlyCssZoom,
|
||||
maxCanvasPixels: this.maxCanvasPixels,
|
||||
|
@ -1289,7 +1300,7 @@ class BaseViewer {
|
|||
* data in forms.
|
||||
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
||||
* for annotation icons. Include trailing slash.
|
||||
* @param {boolean} renderInteractiveForms
|
||||
* @param {boolean} renderForms
|
||||
* @param {IL10n} l10n
|
||||
* @param {boolean} [enableScripting]
|
||||
* @param {Promise<boolean>} [hasJSActionsPromise]
|
||||
|
@ -1301,7 +1312,7 @@ class BaseViewer {
|
|||
pdfPage,
|
||||
annotationStorage = null,
|
||||
imageResourcesPath = "",
|
||||
renderInteractiveForms = false,
|
||||
renderForms = true,
|
||||
l10n = NullL10n,
|
||||
enableScripting = null,
|
||||
hasJSActionsPromise = null,
|
||||
|
@ -1313,7 +1324,7 @@ class BaseViewer {
|
|||
annotationStorage:
|
||||
annotationStorage || this.pdfDocument?.annotationStorage,
|
||||
imageResourcesPath,
|
||||
renderInteractiveForms,
|
||||
renderForms,
|
||||
linkService: this.linkService,
|
||||
downloadManager: this.downloadManager,
|
||||
l10n,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { RenderingCancelledException, shadow } from "pdfjs-lib";
|
||||
import { AnnotationMode, RenderingCancelledException, shadow } from "pdfjs-lib";
|
||||
import { getXfaHtmlForPrinting } from "./print_utils.js";
|
||||
import { PDFPrintServiceFactory } from "./app.js";
|
||||
|
||||
|
@ -68,7 +68,7 @@ function composePage(
|
|||
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
|
||||
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
|
||||
intent: "print",
|
||||
includeAnnotationStorage: true,
|
||||
annotationMode: AnnotationMode.ENABLE_STORAGE,
|
||||
optionalContentConfigPromise,
|
||||
};
|
||||
currentRenderTask = thisRenderTask = pdfPage.render(renderContext);
|
||||
|
|
|
@ -186,7 +186,7 @@ class IPDFAnnotationLayerFactory {
|
|||
* data in forms.
|
||||
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
||||
* for annotation icons. Include trailing slash.
|
||||
* @param {boolean} renderInteractiveForms
|
||||
* @param {boolean} renderForms
|
||||
* @param {IL10n} l10n
|
||||
* @param {boolean} [enableScripting]
|
||||
* @param {Promise<boolean>} [hasJSActionsPromise]
|
||||
|
@ -198,7 +198,7 @@ class IPDFAnnotationLayerFactory {
|
|||
pdfPage,
|
||||
annotationStorage = null,
|
||||
imageResourcesPath = "",
|
||||
renderInteractiveForms = true,
|
||||
renderForms = true,
|
||||
l10n = undefined,
|
||||
enableScripting = false,
|
||||
hasJSActionsPromise = null,
|
||||
|
|
|
@ -13,6 +13,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
AnnotationMode,
|
||||
createPromiseCapability,
|
||||
RenderingCancelledException,
|
||||
SVGGraphics,
|
||||
} from "pdfjs-lib";
|
||||
import {
|
||||
approximateFraction,
|
||||
CSS_UNITS,
|
||||
|
@ -22,11 +28,6 @@ import {
|
|||
roundToDivide,
|
||||
TextLayerMode,
|
||||
} from "./ui_utils.js";
|
||||
import {
|
||||
createPromiseCapability,
|
||||
RenderingCancelledException,
|
||||
SVGGraphics,
|
||||
} from "pdfjs-lib";
|
||||
import { compatibilityParams } from "./app_options.js";
|
||||
import { NullL10n } from "./l10n_utils.js";
|
||||
import { RenderingStates } from "./pdf_rendering_queue.js";
|
||||
|
@ -47,13 +48,16 @@ import { RenderingStates } from "./pdf_rendering_queue.js";
|
|||
* selection and searching is created, and if the improved text selection
|
||||
* behaviour is enabled. The constants from {TextLayerMode} should be used.
|
||||
* The default value is `TextLayerMode.ENABLE`.
|
||||
* @property {number} [annotationMode] - Controls if the annotation layer is
|
||||
* created, and if interactive form elements or `AnnotationStorage`-data are
|
||||
* being rendered. The constants from {@link AnnotationMode} should be used;
|
||||
* see also {@link RenderParameters} and {@link GetOperatorListParameters}.
|
||||
* The default value is `AnnotationMode.ENABLE_FORMS`.
|
||||
* @property {IPDFAnnotationLayerFactory} annotationLayerFactory
|
||||
* @property {IPDFXfaLayerFactory} xfaLayerFactory
|
||||
* @property {IPDFStructTreeLayerFactory} structTreeLayerFactory
|
||||
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||
* for annotation icons. Include trailing slash.
|
||||
* @property {boolean} renderInteractiveForms - Turns on rendering of
|
||||
* interactive form elements. The default value is `true`.
|
||||
* @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'.
|
||||
* @property {boolean} [useOnlyCssZoom] - Enables CSS only zooming. The default
|
||||
* value is `false`.
|
||||
|
@ -88,11 +92,10 @@ class PDFPageView {
|
|||
this._optionalContentConfigPromise =
|
||||
options.optionalContentConfigPromise || null;
|
||||
this.hasRestrictedScaling = false;
|
||||
this.textLayerMode = Number.isInteger(options.textLayerMode)
|
||||
? options.textLayerMode
|
||||
: TextLayerMode.ENABLE;
|
||||
this.textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE;
|
||||
this._annotationMode =
|
||||
options.annotationMode ?? AnnotationMode.ENABLE_FORMS;
|
||||
this.imageResourcesPath = options.imageResourcesPath || "";
|
||||
this.renderInteractiveForms = options.renderInteractiveForms !== false;
|
||||
this.useOnlyCssZoom = options.useOnlyCssZoom || false;
|
||||
this.maxCanvasPixels = options.maxCanvasPixels || MAX_CANVAS_PIXELS;
|
||||
|
||||
|
@ -638,7 +641,10 @@ class PDFPageView {
|
|||
}
|
||||
);
|
||||
|
||||
if (this.annotationLayerFactory) {
|
||||
if (
|
||||
this._annotationMode !== AnnotationMode.DISABLE &&
|
||||
this.annotationLayerFactory
|
||||
) {
|
||||
if (!this.annotationLayer) {
|
||||
this.annotationLayer =
|
||||
this.annotationLayerFactory.createAnnotationLayerBuilder(
|
||||
|
@ -646,9 +652,9 @@ class PDFPageView {
|
|||
pdfPage,
|
||||
/* annotationStorage = */ null,
|
||||
this.imageResourcesPath,
|
||||
this.renderInteractiveForms,
|
||||
this._annotationMode === AnnotationMode.ENABLE_FORMS,
|
||||
this.l10n,
|
||||
/* enableScripting */ null,
|
||||
/* enableScripting = */ null,
|
||||
/* hasJSActionsPromise = */ null,
|
||||
/* mouseState = */ null
|
||||
);
|
||||
|
@ -787,7 +793,7 @@ class PDFPageView {
|
|||
canvasContext: ctx,
|
||||
transform,
|
||||
viewport: this.viewport,
|
||||
renderInteractiveForms: this.renderInteractiveForms,
|
||||
annotationMode: this._annotationMode,
|
||||
optionalContentConfigPromise: this._optionalContentConfigPromise,
|
||||
};
|
||||
const renderTask = this.pdfPage.render(renderContext);
|
||||
|
@ -839,24 +845,28 @@ class PDFPageView {
|
|||
|
||||
const pdfPage = this.pdfPage;
|
||||
const actualSizeViewport = this.viewport.clone({ scale: CSS_UNITS });
|
||||
const promise = pdfPage.getOperatorList().then(opList => {
|
||||
ensureNotCancelled();
|
||||
const svgGfx = new SVGGraphics(
|
||||
pdfPage.commonObjs,
|
||||
pdfPage.objs,
|
||||
/* forceDataSchema = */ compatibilityParams.disableCreateObjectURL
|
||||
);
|
||||
return svgGfx.getSVG(opList, actualSizeViewport).then(svg => {
|
||||
const promise = pdfPage
|
||||
.getOperatorList({
|
||||
annotationMode: this._annotatationMode,
|
||||
})
|
||||
.then(opList => {
|
||||
ensureNotCancelled();
|
||||
this.svg = svg;
|
||||
this.paintedViewportMap.set(svg, actualSizeViewport);
|
||||
const svgGfx = new SVGGraphics(
|
||||
pdfPage.commonObjs,
|
||||
pdfPage.objs,
|
||||
/* forceDataSchema = */ compatibilityParams.disableCreateObjectURL
|
||||
);
|
||||
return svgGfx.getSVG(opList, actualSizeViewport).then(svg => {
|
||||
ensureNotCancelled();
|
||||
this.svg = svg;
|
||||
this.paintedViewportMap.set(svg, actualSizeViewport);
|
||||
|
||||
svg.style.width = wrapper.style.width;
|
||||
svg.style.height = wrapper.style.height;
|
||||
this.renderingState = RenderingStates.FINISHED;
|
||||
wrapper.appendChild(svg);
|
||||
svg.style.width = wrapper.style.width;
|
||||
svg.style.height = wrapper.style.height;
|
||||
this.renderingState = RenderingStates.FINISHED;
|
||||
wrapper.appendChild(svg);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
promise,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
import { PDFPrintServiceFactory, PDFViewerApplication } from "./app.js";
|
||||
import { AnnotationMode } from "pdfjs-lib";
|
||||
import { compatibilityParams } from "./app_options.js";
|
||||
import { getXfaHtmlForPrinting } from "./print_utils.js";
|
||||
|
||||
|
@ -49,7 +50,7 @@ function renderPage(
|
|||
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
|
||||
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
|
||||
intent: "print",
|
||||
includeAnnotationStorage: true,
|
||||
annotationMode: AnnotationMode.ENABLE_STORAGE,
|
||||
optionalContentConfigPromise,
|
||||
};
|
||||
return pdfPage.render(renderContext).promise;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue