[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
@ -144,9 +144,15 @@
|
|||||||
"description": "Whether to prevent the extension from reporting the extension and browser version to the extension developers.",
|
"description": "Whether to prevent the extension from reporting the extension and browser version to the extension developers.",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"renderInteractiveForms": {
|
"annotationMode": {
|
||||||
"type": "boolean",
|
"type": "integer",
|
||||||
"default": true
|
"enum": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"default": 2
|
||||||
},
|
},
|
||||||
"enableScripting": {
|
"enableScripting": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
@ -380,7 +380,10 @@ class Page {
|
|||||||
// page's operator list to render them.
|
// page's operator list to render them.
|
||||||
return Promise.all([pageListPromise, this._parsedAnnotations]).then(
|
return Promise.all([pageListPromise, this._parsedAnnotations]).then(
|
||||||
function ([pageOpList, annotations]) {
|
function ([pageOpList, annotations]) {
|
||||||
if (annotations.length === 0) {
|
if (
|
||||||
|
annotations.length === 0 ||
|
||||||
|
intent & RenderingIntentFlag.ANNOTATIONS_DISABLE
|
||||||
|
) {
|
||||||
pageOpList.flush(true);
|
pageOpList.flush(true);
|
||||||
return { length: pageOpList.totalLength };
|
return { length: pageOpList.totalLength };
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ const DEFAULT_TAB_INDEX = 1000;
|
|||||||
* @property {AnnotationStorage} [annotationStorage]
|
* @property {AnnotationStorage} [annotationStorage]
|
||||||
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||||
* for annotation icons. Include trailing slash.
|
* for annotation icons. Include trailing slash.
|
||||||
* @property {boolean} renderInteractiveForms
|
* @property {boolean} renderForms
|
||||||
* @property {Object} svgFactory
|
* @property {Object} svgFactory
|
||||||
* @property {boolean} [enableScripting]
|
* @property {boolean} [enableScripting]
|
||||||
* @property {boolean} [hasJSActions]
|
* @property {boolean} [hasJSActions]
|
||||||
@ -154,7 +154,7 @@ class AnnotationElement {
|
|||||||
this.linkService = parameters.linkService;
|
this.linkService = parameters.linkService;
|
||||||
this.downloadManager = parameters.downloadManager;
|
this.downloadManager = parameters.downloadManager;
|
||||||
this.imageResourcesPath = parameters.imageResourcesPath;
|
this.imageResourcesPath = parameters.imageResourcesPath;
|
||||||
this.renderInteractiveForms = parameters.renderInteractiveForms;
|
this.renderForms = parameters.renderForms;
|
||||||
this.svgFactory = parameters.svgFactory;
|
this.svgFactory = parameters.svgFactory;
|
||||||
this.annotationStorage = parameters.annotationStorage;
|
this.annotationStorage = parameters.annotationStorage;
|
||||||
this.enableScripting = parameters.enableScripting;
|
this.enableScripting = parameters.enableScripting;
|
||||||
@ -676,7 +676,7 @@ class WidgetAnnotationElement extends AnnotationElement {
|
|||||||
class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
||||||
constructor(parameters) {
|
constructor(parameters) {
|
||||||
const isRenderable =
|
const isRenderable =
|
||||||
parameters.renderInteractiveForms ||
|
parameters.renderForms ||
|
||||||
(!parameters.data.hasAppearance && !!parameters.data.fieldValue);
|
(!parameters.data.hasAppearance && !!parameters.data.fieldValue);
|
||||||
super(parameters, { isRenderable });
|
super(parameters, { isRenderable });
|
||||||
}
|
}
|
||||||
@ -700,7 +700,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
this.container.className = "textWidgetAnnotation";
|
this.container.className = "textWidgetAnnotation";
|
||||||
|
|
||||||
let element = null;
|
let element = null;
|
||||||
if (this.renderInteractiveForms) {
|
if (this.renderForms) {
|
||||||
// NOTE: We cannot set the values using `element.value` below, since it
|
// NOTE: We cannot set the values using `element.value` below, since it
|
||||||
// prevents the AnnotationLayer rasterizer in `test/driver.js`
|
// prevents the AnnotationLayer rasterizer in `test/driver.js`
|
||||||
// from parsing the elements correctly for the reference tests.
|
// from parsing the elements correctly for the reference tests.
|
||||||
@ -952,7 +952,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
|
|
||||||
class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
|
class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
|
||||||
constructor(parameters) {
|
constructor(parameters) {
|
||||||
super(parameters, { isRenderable: parameters.renderInteractiveForms });
|
super(parameters, { isRenderable: parameters.renderForms });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -1031,7 +1031,7 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||||||
|
|
||||||
class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
|
class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
|
||||||
constructor(parameters) {
|
constructor(parameters) {
|
||||||
super(parameters, { isRenderable: parameters.renderInteractiveForms });
|
super(parameters, { isRenderable: parameters.renderForms });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -1123,7 +1123,7 @@ class PushButtonWidgetAnnotationElement extends LinkAnnotationElement {
|
|||||||
|
|
||||||
class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
||||||
constructor(parameters) {
|
constructor(parameters) {
|
||||||
super(parameters, { isRenderable: parameters.renderInteractiveForms });
|
super(parameters, { isRenderable: parameters.renderForms });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -2033,7 +2033,7 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
|
|||||||
* @property {DownloadManager} downloadManager
|
* @property {DownloadManager} downloadManager
|
||||||
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||||
* for annotation icons. Include trailing slash.
|
* for annotation icons. Include trailing slash.
|
||||||
* @property {boolean} renderInteractiveForms
|
* @property {boolean} renderForms
|
||||||
* @property {boolean} [enableScripting] - Enable embedded script execution.
|
* @property {boolean} [enableScripting] - Enable embedded script execution.
|
||||||
* @property {boolean} [hasJSActions] - Some fields have JS actions.
|
* @property {boolean} [hasJSActions] - Some fields have JS actions.
|
||||||
* The default value is `false`.
|
* The default value is `false`.
|
||||||
@ -2076,7 +2076,7 @@ class AnnotationLayer {
|
|||||||
linkService: parameters.linkService,
|
linkService: parameters.linkService,
|
||||||
downloadManager: parameters.downloadManager,
|
downloadManager: parameters.downloadManager,
|
||||||
imageResourcesPath: parameters.imageResourcesPath || "",
|
imageResourcesPath: parameters.imageResourcesPath || "",
|
||||||
renderInteractiveForms: parameters.renderInteractiveForms !== false,
|
renderForms: parameters.renderForms !== false,
|
||||||
svgFactory: new DOMSVGFactory(),
|
svgFactory: new DOMSVGFactory(),
|
||||||
annotationStorage:
|
annotationStorage:
|
||||||
parameters.annotationStorage || new AnnotationStorage(),
|
parameters.annotationStorage || new AnnotationStorage(),
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AbortException,
|
AbortException,
|
||||||
|
AnnotationMode,
|
||||||
assert,
|
assert,
|
||||||
createPromiseCapability,
|
createPromiseCapability,
|
||||||
getVerbosityLevel,
|
getVerbosityLevel,
|
||||||
@ -1135,9 +1136,18 @@ class PDFDocumentProxy {
|
|||||||
* the `PDFPageProxy.getViewport` method.
|
* the `PDFPageProxy.getViewport` method.
|
||||||
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
|
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
|
||||||
* or 'any'. The default value is 'display'.
|
* or 'any'. The default value is 'display'.
|
||||||
* @property {boolean} [renderInteractiveForms] - Whether or not interactive
|
* @property {number} [annotationMode] Controls which annotations are rendered
|
||||||
* form elements are rendered in the display layer. If so, we do not render
|
* onto the canvas, for annotations with appearance-data; the values from
|
||||||
* them on the canvas as well. The default value is `false`.
|
* {@link AnnotationMode} should be used. The following values are supported:
|
||||||
|
* - `AnnotationMode.DISABLE`, which disables all annotations.
|
||||||
|
* - `AnnotationMode.ENABLE`, which includes all possible annotations (thus
|
||||||
|
* it also depends on the `intent`-option, see above).
|
||||||
|
* - `AnnotationMode.ENABLE_FORMS`, which excludes annotations that contain
|
||||||
|
* interactive form elements (those will be rendered in the display layer).
|
||||||
|
* - `AnnotationMode.ENABLE_STORAGE`, which includes all possible annotations
|
||||||
|
* (as above) but where interactive form elements are updated with data
|
||||||
|
* from the {@link AnnotationStorage}-instance; useful e.g. for printing.
|
||||||
|
* The default value is `AnnotationMode.ENABLE`.
|
||||||
* @property {Array<any>} [transform] - Additional transform, applied just
|
* @property {Array<any>} [transform] - Additional transform, applied just
|
||||||
* before viewport transform.
|
* before viewport transform.
|
||||||
* @property {Object} [imageLayer] - An object that has `beginLayout`,
|
* @property {Object} [imageLayer] - An object that has `beginLayout`,
|
||||||
@ -1149,9 +1159,6 @@ class PDFDocumentProxy {
|
|||||||
* <color> value, a `CanvasGradient` object (a linear or radial gradient) or
|
* <color> value, a `CanvasGradient` object (a linear or radial gradient) or
|
||||||
* a `CanvasPattern` object (a repetitive image). The default value is
|
* a `CanvasPattern` object (a repetitive image). The default value is
|
||||||
* 'rgb(255,255,255)'.
|
* 'rgb(255,255,255)'.
|
||||||
* @property {boolean} [includeAnnotationStorage] - Render stored interactive
|
|
||||||
* form element data, from the {@link AnnotationStorage}-instance, onto the
|
|
||||||
* canvas itself; useful e.g. for printing. The default value is `false`.
|
|
||||||
* @property {Promise<OptionalContentConfig>} [optionalContentConfigPromise] -
|
* @property {Promise<OptionalContentConfig>} [optionalContentConfigPromise] -
|
||||||
* A promise that should resolve with an {@link OptionalContentConfig}
|
* A promise that should resolve with an {@link OptionalContentConfig}
|
||||||
* created from `PDFDocumentProxy.getOptionalContentConfig`. If `null`,
|
* created from `PDFDocumentProxy.getOptionalContentConfig`. If `null`,
|
||||||
@ -1165,6 +1172,18 @@ class PDFDocumentProxy {
|
|||||||
* @typedef {Object} GetOperatorListParameters
|
* @typedef {Object} GetOperatorListParameters
|
||||||
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
|
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
|
||||||
* or 'any'. The default value is 'display'.
|
* or 'any'. The default value is 'display'.
|
||||||
|
* @property {number} [annotationMode] Controls which annotations are included
|
||||||
|
* in the operatorList, for annotations with appearance-data; the values from
|
||||||
|
* {@link AnnotationMode} should be used. The following values are supported:
|
||||||
|
* - `AnnotationMode.DISABLE`, which disables all annotations.
|
||||||
|
* - `AnnotationMode.ENABLE`, which includes all possible annotations (thus
|
||||||
|
* it also depends on the `intent`-option, see above).
|
||||||
|
* - `AnnotationMode.ENABLE_FORMS`, which excludes annotations that contain
|
||||||
|
* interactive form elements (those will be rendered in the display layer).
|
||||||
|
* - `AnnotationMode.ENABLE_STORAGE`, which includes all possible annotations
|
||||||
|
* (as above) but where interactive form elements are updated with data
|
||||||
|
* from the {@link AnnotationStorage}-instance; useful e.g. for printing.
|
||||||
|
* The default value is `AnnotationMode.ENABLE`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1280,7 +1299,7 @@ class PDFPageProxy {
|
|||||||
* {Array} of the annotation objects.
|
* {Array} of the annotation objects.
|
||||||
*/
|
*/
|
||||||
getAnnotations({ intent = "display" } = {}) {
|
getAnnotations({ intent = "display" } = {}) {
|
||||||
const intentArgs = this._transport.getRenderingIntent(intent, {});
|
const intentArgs = this._transport.getRenderingIntent(intent);
|
||||||
|
|
||||||
let promise = this._annotationPromises.get(intentArgs.cacheKey);
|
let promise = this._annotationPromises.get(intentArgs.cacheKey);
|
||||||
if (!promise) {
|
if (!promise) {
|
||||||
@ -1324,22 +1343,21 @@ class PDFPageProxy {
|
|||||||
canvasContext,
|
canvasContext,
|
||||||
viewport,
|
viewport,
|
||||||
intent = "display",
|
intent = "display",
|
||||||
renderInteractiveForms = false,
|
annotationMode = AnnotationMode.ENABLE,
|
||||||
transform = null,
|
transform = null,
|
||||||
imageLayer = null,
|
imageLayer = null,
|
||||||
canvasFactory = null,
|
canvasFactory = null,
|
||||||
background = null,
|
background = null,
|
||||||
includeAnnotationStorage = false,
|
|
||||||
optionalContentConfigPromise = null,
|
optionalContentConfigPromise = null,
|
||||||
}) {
|
}) {
|
||||||
if (this._stats) {
|
if (this._stats) {
|
||||||
this._stats.time("Overall");
|
this._stats.time("Overall");
|
||||||
}
|
}
|
||||||
|
|
||||||
const intentArgs = this._transport.getRenderingIntent(intent, {
|
const intentArgs = this._transport.getRenderingIntent(
|
||||||
renderForms: renderInteractiveForms === true,
|
intent,
|
||||||
includeAnnotationStorage: includeAnnotationStorage === true,
|
annotationMode
|
||||||
});
|
);
|
||||||
// If there was a pending destroy, cancel it so no cleanup happens during
|
// If there was a pending destroy, cancel it so no cleanup happens during
|
||||||
// this call to render.
|
// this call to render.
|
||||||
this.pendingCleanup = false;
|
this.pendingCleanup = false;
|
||||||
@ -1460,7 +1478,10 @@ class PDFPageProxy {
|
|||||||
* @returns {Promise<PDFOperatorList>} A promise resolved with an
|
* @returns {Promise<PDFOperatorList>} A promise resolved with an
|
||||||
* {@link PDFOperatorList} object that represents the page's operator list.
|
* {@link PDFOperatorList} object that represents the page's operator list.
|
||||||
*/
|
*/
|
||||||
getOperatorList({ intent = "display" } = {}) {
|
getOperatorList({
|
||||||
|
intent = "display",
|
||||||
|
annotationMode = AnnotationMode.ENABLE,
|
||||||
|
} = {}) {
|
||||||
function operatorListChanged() {
|
function operatorListChanged() {
|
||||||
if (intentState.operatorList.lastChunk) {
|
if (intentState.operatorList.lastChunk) {
|
||||||
intentState.opListReadCapability.resolve(intentState.operatorList);
|
intentState.opListReadCapability.resolve(intentState.operatorList);
|
||||||
@ -1469,9 +1490,11 @@ class PDFPageProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const intentArgs = this._transport.getRenderingIntent(intent, {
|
const intentArgs = this._transport.getRenderingIntent(
|
||||||
isOpList: true,
|
intent,
|
||||||
});
|
annotationMode,
|
||||||
|
/* isOpList = */ true
|
||||||
|
);
|
||||||
let intentState = this._intentStates.get(intentArgs.cacheKey);
|
let intentState = this._intentStates.get(intentArgs.cacheKey);
|
||||||
if (!intentState) {
|
if (!intentState) {
|
||||||
intentState = Object.create(null);
|
intentState = Object.create(null);
|
||||||
@ -1792,7 +1815,7 @@ class PDFPageProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
intentState.streamReader
|
intentState.streamReader
|
||||||
.cancel(new AbortException(reason?.message))
|
.cancel(new AbortException(reason.message))
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
// Avoid "Uncaught promise" messages in the console.
|
// Avoid "Uncaught promise" messages in the console.
|
||||||
});
|
});
|
||||||
@ -2351,7 +2374,8 @@ class WorkerTransport {
|
|||||||
|
|
||||||
getRenderingIntent(
|
getRenderingIntent(
|
||||||
intent,
|
intent,
|
||||||
{ renderForms = false, includeAnnotationStorage = false, isOpList = false }
|
annotationMode = AnnotationMode.ENABLE,
|
||||||
|
isOpList = false
|
||||||
) {
|
) {
|
||||||
let renderingIntent = RenderingIntentFlag.DISPLAY; // Default value.
|
let renderingIntent = RenderingIntentFlag.DISPLAY; // Default value.
|
||||||
let lastModified = "";
|
let lastModified = "";
|
||||||
@ -2369,13 +2393,22 @@ class WorkerTransport {
|
|||||||
warn(`getRenderingIntent - invalid intent: ${intent}`);
|
warn(`getRenderingIntent - invalid intent: ${intent}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderForms) {
|
switch (annotationMode) {
|
||||||
renderingIntent += RenderingIntentFlag.ANNOTATIONS_FORMS;
|
case AnnotationMode.DISABLE:
|
||||||
}
|
renderingIntent += RenderingIntentFlag.ANNOTATIONS_DISABLE;
|
||||||
if (includeAnnotationStorage) {
|
break;
|
||||||
renderingIntent += RenderingIntentFlag.ANNOTATIONS_STORAGE;
|
case AnnotationMode.ENABLE:
|
||||||
|
break;
|
||||||
|
case AnnotationMode.ENABLE_FORMS:
|
||||||
|
renderingIntent += RenderingIntentFlag.ANNOTATIONS_FORMS;
|
||||||
|
break;
|
||||||
|
case AnnotationMode.ENABLE_STORAGE:
|
||||||
|
renderingIntent += RenderingIntentFlag.ANNOTATIONS_STORAGE;
|
||||||
|
|
||||||
lastModified = this.annotationStorage.lastModified;
|
lastModified = this.annotationStorage.lastModified;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warn(`getRenderingIntent - invalid annotationMode: ${annotationMode}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOpList) {
|
if (isOpList) {
|
||||||
|
34
src/pdf.js
34
src/pdf.js
@ -27,15 +27,7 @@ import {
|
|||||||
RenderingCancelledException,
|
RenderingCancelledException,
|
||||||
} from "./display/display_utils.js";
|
} from "./display/display_utils.js";
|
||||||
import {
|
import {
|
||||||
build,
|
AnnotationMode,
|
||||||
getDocument,
|
|
||||||
LoopbackPort,
|
|
||||||
PDFDataRangeTransport,
|
|
||||||
PDFWorker,
|
|
||||||
setPDFNetworkStreamFactory,
|
|
||||||
version,
|
|
||||||
} from "./display/api.js";
|
|
||||||
import {
|
|
||||||
CMapCompressionType,
|
CMapCompressionType,
|
||||||
createObjectURL,
|
createObjectURL,
|
||||||
createPromiseCapability,
|
createPromiseCapability,
|
||||||
@ -52,6 +44,15 @@ import {
|
|||||||
Util,
|
Util,
|
||||||
VerbosityLevel,
|
VerbosityLevel,
|
||||||
} from "./shared/util.js";
|
} from "./shared/util.js";
|
||||||
|
import {
|
||||||
|
build,
|
||||||
|
getDocument,
|
||||||
|
LoopbackPort,
|
||||||
|
PDFDataRangeTransport,
|
||||||
|
PDFWorker,
|
||||||
|
setPDFNetworkStreamFactory,
|
||||||
|
version,
|
||||||
|
} from "./display/api.js";
|
||||||
import { AnnotationLayer } from "./display/annotation_layer.js";
|
import { AnnotationLayer } from "./display/annotation_layer.js";
|
||||||
import { GlobalWorkerOptions } from "./display/worker_options.js";
|
import { GlobalWorkerOptions } from "./display/worker_options.js";
|
||||||
import { isNodeJS } from "./shared/is_node.js";
|
import { isNodeJS } from "./shared/is_node.js";
|
||||||
@ -110,14 +111,8 @@ export {
|
|||||||
PDFDateString,
|
PDFDateString,
|
||||||
RenderingCancelledException,
|
RenderingCancelledException,
|
||||||
getXfaPageViewport,
|
getXfaPageViewport,
|
||||||
// From "./display/api.js":
|
|
||||||
build,
|
|
||||||
getDocument,
|
|
||||||
LoopbackPort,
|
|
||||||
PDFDataRangeTransport,
|
|
||||||
PDFWorker,
|
|
||||||
version,
|
|
||||||
// From "./shared/util.js":
|
// From "./shared/util.js":
|
||||||
|
AnnotationMode,
|
||||||
CMapCompressionType,
|
CMapCompressionType,
|
||||||
createObjectURL,
|
createObjectURL,
|
||||||
createPromiseCapability,
|
createPromiseCapability,
|
||||||
@ -133,6 +128,13 @@ export {
|
|||||||
UNSUPPORTED_FEATURES,
|
UNSUPPORTED_FEATURES,
|
||||||
Util,
|
Util,
|
||||||
VerbosityLevel,
|
VerbosityLevel,
|
||||||
|
// From "./display/api.js":
|
||||||
|
build,
|
||||||
|
getDocument,
|
||||||
|
LoopbackPort,
|
||||||
|
PDFDataRangeTransport,
|
||||||
|
PDFWorker,
|
||||||
|
version,
|
||||||
// From "./display/annotation_layer.js":
|
// From "./display/annotation_layer.js":
|
||||||
AnnotationLayer,
|
AnnotationLayer,
|
||||||
// From "./display/worker_options.js":
|
// From "./display/worker_options.js":
|
||||||
|
@ -23,9 +23,10 @@ const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
|||||||
* how these flags are being used:
|
* how these flags are being used:
|
||||||
* - ANY, DISPLAY, and PRINT are the normal rendering intents, note the
|
* - ANY, DISPLAY, and PRINT are the normal rendering intents, note the
|
||||||
* `PDFPageProxy.{render, getOperatorList, getAnnotations}`-methods.
|
* `PDFPageProxy.{render, getOperatorList, getAnnotations}`-methods.
|
||||||
* - ANNOTATIONS_FORMS, and ANNOTATIONS_STORAGE controls which annotations are
|
* - ANNOTATIONS_FORMS, ANNOTATIONS_STORAGE, ANNOTATIONS_DISABLE control which
|
||||||
* rendered onto the canvas, note the `renderInteractiveForms`- respectively
|
* annotations are rendered onto the canvas (i.e. by being included in the
|
||||||
* `includeAnnotationStorage`-options in the `PDFPageProxy.render`-method.
|
* operatorList), note the `PDFPageProxy.{render, getOperatorList}`-methods
|
||||||
|
* and their `annotationMode`-option.
|
||||||
* - OPLIST is used with the `PDFPageProxy.getOperatorList`-method, note the
|
* - OPLIST is used with the `PDFPageProxy.getOperatorList`-method, note the
|
||||||
* `OperatorList`-constructor (on the worker-thread).
|
* `OperatorList`-constructor (on the worker-thread).
|
||||||
*/
|
*/
|
||||||
@ -35,9 +36,17 @@ const RenderingIntentFlag = {
|
|||||||
PRINT: 0x04,
|
PRINT: 0x04,
|
||||||
ANNOTATIONS_FORMS: 0x10,
|
ANNOTATIONS_FORMS: 0x10,
|
||||||
ANNOTATIONS_STORAGE: 0x20,
|
ANNOTATIONS_STORAGE: 0x20,
|
||||||
|
ANNOTATIONS_DISABLE: 0x40,
|
||||||
OPLIST: 0x100,
|
OPLIST: 0x100,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AnnotationMode = {
|
||||||
|
DISABLE: 0,
|
||||||
|
ENABLE: 1,
|
||||||
|
ENABLE_FORMS: 2,
|
||||||
|
ENABLE_STORAGE: 3,
|
||||||
|
};
|
||||||
|
|
||||||
// Permission flags from Table 22, Section 7.6.3.2 of the PDF specification.
|
// Permission flags from Table 22, Section 7.6.3.2 of the PDF specification.
|
||||||
const PermissionFlag = {
|
const PermissionFlag = {
|
||||||
PRINT: 0x04,
|
PRINT: 0x04,
|
||||||
@ -1027,6 +1036,7 @@ export {
|
|||||||
AnnotationFieldFlag,
|
AnnotationFieldFlag,
|
||||||
AnnotationFlag,
|
AnnotationFlag,
|
||||||
AnnotationMarkedState,
|
AnnotationMarkedState,
|
||||||
|
AnnotationMode,
|
||||||
AnnotationReplyType,
|
AnnotationReplyType,
|
||||||
AnnotationReviewState,
|
AnnotationReviewState,
|
||||||
AnnotationStateModelType,
|
AnnotationStateModelType,
|
||||||
|
@ -17,6 +17,16 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const {
|
||||||
|
AnnotationLayer,
|
||||||
|
AnnotationMode,
|
||||||
|
getDocument,
|
||||||
|
GlobalWorkerOptions,
|
||||||
|
renderTextLayer,
|
||||||
|
XfaLayer,
|
||||||
|
} = pdfjsLib;
|
||||||
|
const { SimpleLinkService } = pdfjsViewer;
|
||||||
|
|
||||||
const WAITING_TIME = 100; // ms
|
const WAITING_TIME = 100; // ms
|
||||||
const PDF_TO_CSS_UNITS = 96.0 / 72.0;
|
const PDF_TO_CSS_UNITS = 96.0 / 72.0;
|
||||||
const CMAP_URL = "/build/generic/web/cmaps/";
|
const CMAP_URL = "/build/generic/web/cmaps/";
|
||||||
@ -162,7 +172,7 @@ var rasterizeTextLayer = (function rasterizeTextLayerClosure() {
|
|||||||
style.textContent = cssRules;
|
style.textContent = cssRules;
|
||||||
|
|
||||||
// Rendering text layer as HTML.
|
// Rendering text layer as HTML.
|
||||||
var task = pdfjsLib.renderTextLayer({
|
var task = renderTextLayer({
|
||||||
textContent,
|
textContent,
|
||||||
container: div,
|
container: div,
|
||||||
viewport,
|
viewport,
|
||||||
@ -219,7 +229,7 @@ var rasterizeAnnotationLayer = (function rasterizeAnnotationLayerClosure() {
|
|||||||
annotations,
|
annotations,
|
||||||
page,
|
page,
|
||||||
imageResourcesPath,
|
imageResourcesPath,
|
||||||
renderInteractiveForms
|
renderForms = false
|
||||||
) {
|
) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
// Building SVG with size of the viewport.
|
// Building SVG with size of the viewport.
|
||||||
@ -250,11 +260,11 @@ var rasterizeAnnotationLayer = (function rasterizeAnnotationLayerClosure() {
|
|||||||
div,
|
div,
|
||||||
annotations,
|
annotations,
|
||||||
page,
|
page,
|
||||||
linkService: new pdfjsViewer.SimpleLinkService(),
|
linkService: new SimpleLinkService(),
|
||||||
imageResourcesPath,
|
imageResourcesPath,
|
||||||
renderInteractiveForms,
|
renderForms,
|
||||||
};
|
};
|
||||||
pdfjsLib.AnnotationLayer.render(parameters);
|
AnnotationLayer.render(parameters);
|
||||||
|
|
||||||
// Inline SVG images from text annotations.
|
// Inline SVG images from text annotations.
|
||||||
await resolveImages(div);
|
await resolveImages(div);
|
||||||
@ -319,7 +329,7 @@ var rasterizeXfaLayer = (function rasterizeXfaLayerClosure() {
|
|||||||
.then(async cssRules => {
|
.then(async cssRules => {
|
||||||
style.textContent = fontRules + "\n" + cssRules;
|
style.textContent = fontRules + "\n" + cssRules;
|
||||||
|
|
||||||
pdfjsLib.XfaLayer.render({
|
XfaLayer.render({
|
||||||
xfa,
|
xfa,
|
||||||
div,
|
div,
|
||||||
viewport: viewport.clone({ dontFlip: true }),
|
viewport: viewport.clone({ dontFlip: true }),
|
||||||
@ -365,7 +375,7 @@ var Driver = (function DriverClosure() {
|
|||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
function Driver(options) {
|
function Driver(options) {
|
||||||
// Configure the global worker options.
|
// Configure the global worker options.
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc = WORKER_SRC;
|
GlobalWorkerOptions.workerSrc = WORKER_SRC;
|
||||||
|
|
||||||
// Set the passed options
|
// Set the passed options
|
||||||
this.inflight = options.inflight;
|
this.inflight = options.inflight;
|
||||||
@ -494,7 +504,7 @@ var Driver = (function DriverClosure() {
|
|||||||
.appendChild(xfaStyleElement);
|
.appendChild(xfaStyleElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadingTask = pdfjsLib.getDocument({
|
const loadingTask = getDocument({
|
||||||
url: absoluteUrl,
|
url: absoluteUrl,
|
||||||
password: task.password,
|
password: task.password,
|
||||||
cMapUrl: CMAP_URL,
|
cMapUrl: CMAP_URL,
|
||||||
@ -752,12 +762,13 @@ var Driver = (function DriverClosure() {
|
|||||||
var renderContext = {
|
var renderContext = {
|
||||||
canvasContext: ctx,
|
canvasContext: ctx,
|
||||||
viewport,
|
viewport,
|
||||||
renderInteractiveForms: renderForms,
|
|
||||||
optionalContentConfigPromise: task.optionalContentConfigPromise,
|
optionalContentConfigPromise: task.optionalContentConfigPromise,
|
||||||
};
|
};
|
||||||
if (renderPrint) {
|
if (renderForms) {
|
||||||
|
renderContext.annotationMode = AnnotationMode.ENABLE_FORMS;
|
||||||
|
} else if (renderPrint) {
|
||||||
if (task.annotationStorage) {
|
if (task.annotationStorage) {
|
||||||
renderContext.includeAnnotationStorage = true;
|
renderContext.annotationMode = AnnotationMode.ENABLE_STORAGE;
|
||||||
}
|
}
|
||||||
renderContext.intent = "print";
|
renderContext.intent = "print";
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
buildGetDocumentParams,
|
AnnotationMode,
|
||||||
DefaultFileReaderFactory,
|
|
||||||
TEST_PDFS_PATH,
|
|
||||||
} from "./test_utils.js";
|
|
||||||
import {
|
|
||||||
createPromiseCapability,
|
createPromiseCapability,
|
||||||
FontType,
|
FontType,
|
||||||
ImageKind,
|
ImageKind,
|
||||||
@ -30,6 +26,11 @@ import {
|
|||||||
PermissionFlag,
|
PermissionFlag,
|
||||||
StreamType,
|
StreamType,
|
||||||
} from "../../src/shared/util.js";
|
} from "../../src/shared/util.js";
|
||||||
|
import {
|
||||||
|
buildGetDocumentParams,
|
||||||
|
DefaultFileReaderFactory,
|
||||||
|
TEST_PDFS_PATH,
|
||||||
|
} from "./test_utils.js";
|
||||||
import {
|
import {
|
||||||
DefaultCanvasFactory,
|
DefaultCanvasFactory,
|
||||||
getDocument,
|
getDocument,
|
||||||
@ -1739,6 +1740,56 @@ describe("api", function () {
|
|||||||
await loadingTask.destroy();
|
await loadingTask.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("gets operator list, with `annotationMode`-option", async function () {
|
||||||
|
const loadingTask = getDocument(buildGetDocumentParams("evaljs.pdf"));
|
||||||
|
const pdfDoc = await loadingTask.promise;
|
||||||
|
const pdfPage = await pdfDoc.getPage(2);
|
||||||
|
|
||||||
|
pdfDoc.annotationStorage.setValue("30R", { value: "test" });
|
||||||
|
pdfDoc.annotationStorage.setValue("31R", { value: true });
|
||||||
|
|
||||||
|
const opListAnnotDisable = await pdfPage.getOperatorList({
|
||||||
|
annotationMode: AnnotationMode.DISABLE,
|
||||||
|
});
|
||||||
|
expect(opListAnnotDisable.fnArray.length).toEqual(0);
|
||||||
|
expect(opListAnnotDisable.argsArray.length).toEqual(0);
|
||||||
|
expect(opListAnnotDisable.lastChunk).toEqual(true);
|
||||||
|
|
||||||
|
const opListAnnotEnable = await pdfPage.getOperatorList({
|
||||||
|
annotationMode: AnnotationMode.ENABLE,
|
||||||
|
});
|
||||||
|
expect(opListAnnotEnable.fnArray.length).toBeGreaterThan(150);
|
||||||
|
expect(opListAnnotEnable.argsArray.length).toBeGreaterThan(150);
|
||||||
|
expect(opListAnnotEnable.lastChunk).toEqual(true);
|
||||||
|
|
||||||
|
const opListAnnotEnableForms = await pdfPage.getOperatorList({
|
||||||
|
annotationMode: AnnotationMode.ENABLE_FORMS,
|
||||||
|
});
|
||||||
|
expect(opListAnnotEnableForms.fnArray.length).toBeGreaterThan(40);
|
||||||
|
expect(opListAnnotEnableForms.argsArray.length).toBeGreaterThan(40);
|
||||||
|
expect(opListAnnotEnableForms.lastChunk).toEqual(true);
|
||||||
|
|
||||||
|
const opListAnnotEnableStorage = await pdfPage.getOperatorList({
|
||||||
|
annotationMode: AnnotationMode.ENABLE_STORAGE,
|
||||||
|
});
|
||||||
|
expect(opListAnnotEnableStorage.fnArray.length).toBeGreaterThan(170);
|
||||||
|
expect(opListAnnotEnableStorage.argsArray.length).toBeGreaterThan(170);
|
||||||
|
expect(opListAnnotEnableStorage.lastChunk).toEqual(true);
|
||||||
|
|
||||||
|
// Sanity check to ensure that the `annotationMode` is correctly applied.
|
||||||
|
expect(opListAnnotDisable.fnArray.length).toBeLessThan(
|
||||||
|
opListAnnotEnableForms.fnArray.length
|
||||||
|
);
|
||||||
|
expect(opListAnnotEnableForms.fnArray.length).toBeLessThan(
|
||||||
|
opListAnnotEnable.fnArray.length
|
||||||
|
);
|
||||||
|
expect(opListAnnotEnable.fnArray.length).toBeLessThan(
|
||||||
|
opListAnnotEnableStorage.fnArray.length
|
||||||
|
);
|
||||||
|
|
||||||
|
await loadingTask.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it("gets document stats after parsing page", async function () {
|
it("gets document stats after parsing page", async function () {
|
||||||
const stats = await page.getOperatorList().then(function () {
|
const stats = await page.getOperatorList().then(function () {
|
||||||
return pdfDocument.getStats();
|
return pdfDocument.getStats();
|
||||||
|
@ -24,7 +24,7 @@ import { SimpleLinkService } from "./pdf_link_service.js";
|
|||||||
* @property {AnnotationStorage} [annotationStorage]
|
* @property {AnnotationStorage} [annotationStorage]
|
||||||
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||||
* for annotation icons. Include trailing slash.
|
* for annotation icons. Include trailing slash.
|
||||||
* @property {boolean} renderInteractiveForms
|
* @property {boolean} renderForms
|
||||||
* @property {IPDFLinkService} linkService
|
* @property {IPDFLinkService} linkService
|
||||||
* @property {DownloadManager} downloadManager
|
* @property {DownloadManager} downloadManager
|
||||||
* @property {IL10n} l10n - Localization service.
|
* @property {IL10n} l10n - Localization service.
|
||||||
@ -44,7 +44,7 @@ class AnnotationLayerBuilder {
|
|||||||
downloadManager,
|
downloadManager,
|
||||||
annotationStorage = null,
|
annotationStorage = null,
|
||||||
imageResourcesPath = "",
|
imageResourcesPath = "",
|
||||||
renderInteractiveForms = true,
|
renderForms = true,
|
||||||
l10n = NullL10n,
|
l10n = NullL10n,
|
||||||
enableScripting = false,
|
enableScripting = false,
|
||||||
hasJSActionsPromise = null,
|
hasJSActionsPromise = null,
|
||||||
@ -55,7 +55,7 @@ class AnnotationLayerBuilder {
|
|||||||
this.linkService = linkService;
|
this.linkService = linkService;
|
||||||
this.downloadManager = downloadManager;
|
this.downloadManager = downloadManager;
|
||||||
this.imageResourcesPath = imageResourcesPath;
|
this.imageResourcesPath = imageResourcesPath;
|
||||||
this.renderInteractiveForms = renderInteractiveForms;
|
this.renderForms = renderForms;
|
||||||
this.l10n = l10n;
|
this.l10n = l10n;
|
||||||
this.annotationStorage = annotationStorage;
|
this.annotationStorage = annotationStorage;
|
||||||
this.enableScripting = enableScripting;
|
this.enableScripting = enableScripting;
|
||||||
@ -90,7 +90,7 @@ class AnnotationLayerBuilder {
|
|||||||
annotations,
|
annotations,
|
||||||
page: this.pdfPage,
|
page: this.pdfPage,
|
||||||
imageResourcesPath: this.imageResourcesPath,
|
imageResourcesPath: this.imageResourcesPath,
|
||||||
renderInteractiveForms: this.renderInteractiveForms,
|
renderForms: this.renderForms,
|
||||||
linkService: this.linkService,
|
linkService: this.linkService,
|
||||||
downloadManager: this.downloadManager,
|
downloadManager: this.downloadManager,
|
||||||
annotationStorage: this.annotationStorage,
|
annotationStorage: this.annotationStorage,
|
||||||
@ -139,7 +139,7 @@ class DefaultAnnotationLayerFactory {
|
|||||||
* @param {AnnotationStorage} [annotationStorage]
|
* @param {AnnotationStorage} [annotationStorage]
|
||||||
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
||||||
* for annotation icons. Include trailing slash.
|
* for annotation icons. Include trailing slash.
|
||||||
* @param {boolean} renderInteractiveForms
|
* @param {boolean} renderForms
|
||||||
* @param {IL10n} l10n
|
* @param {IL10n} l10n
|
||||||
* @param {boolean} [enableScripting]
|
* @param {boolean} [enableScripting]
|
||||||
* @param {Promise<boolean>} [hasJSActionsPromise]
|
* @param {Promise<boolean>} [hasJSActionsPromise]
|
||||||
@ -151,7 +151,7 @@ class DefaultAnnotationLayerFactory {
|
|||||||
pdfPage,
|
pdfPage,
|
||||||
annotationStorage = null,
|
annotationStorage = null,
|
||||||
imageResourcesPath = "",
|
imageResourcesPath = "",
|
||||||
renderInteractiveForms = true,
|
renderForms = true,
|
||||||
l10n = NullL10n,
|
l10n = NullL10n,
|
||||||
enableScripting = false,
|
enableScripting = false,
|
||||||
hasJSActionsPromise = null,
|
hasJSActionsPromise = null,
|
||||||
@ -161,7 +161,7 @@ class DefaultAnnotationLayerFactory {
|
|||||||
pageDiv,
|
pageDiv,
|
||||||
pdfPage,
|
pdfPage,
|
||||||
imageResourcesPath,
|
imageResourcesPath,
|
||||||
renderInteractiveForms,
|
renderForms,
|
||||||
linkService: new SimpleLinkService(),
|
linkService: new SimpleLinkService(),
|
||||||
l10n,
|
l10n,
|
||||||
annotationStorage,
|
annotationStorage,
|
||||||
|
@ -515,8 +515,8 @@ const PDFViewerApplication = {
|
|||||||
renderer: AppOptions.get("renderer"),
|
renderer: AppOptions.get("renderer"),
|
||||||
l10n: this.l10n,
|
l10n: this.l10n,
|
||||||
textLayerMode: AppOptions.get("textLayerMode"),
|
textLayerMode: AppOptions.get("textLayerMode"),
|
||||||
|
annotationMode: AppOptions.get("annotationMode"),
|
||||||
imageResourcesPath: AppOptions.get("imageResourcesPath"),
|
imageResourcesPath: AppOptions.get("imageResourcesPath"),
|
||||||
renderInteractiveForms: AppOptions.get("renderInteractiveForms"),
|
|
||||||
enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),
|
enablePrintAutoRotate: AppOptions.get("enablePrintAutoRotate"),
|
||||||
useOnlyCssZoom: AppOptions.get("useOnlyCssZoom"),
|
useOnlyCssZoom: AppOptions.get("useOnlyCssZoom"),
|
||||||
maxCanvasPixels: AppOptions.get("maxCanvasPixels"),
|
maxCanvasPixels: AppOptions.get("maxCanvasPixels"),
|
||||||
@ -1555,7 +1555,7 @@ const PDFViewerApplication = {
|
|||||||
this.fallback(UNSUPPORTED_FEATURES.forms);
|
this.fallback(UNSUPPORTED_FEATURES.forms);
|
||||||
} else if (
|
} else if (
|
||||||
(info.IsAcroFormPresent || info.IsXFAPresent) &&
|
(info.IsAcroFormPresent || info.IsXFAPresent) &&
|
||||||
!this.pdfViewer.renderInteractiveForms
|
!this.pdfViewer.renderForms
|
||||||
) {
|
) {
|
||||||
console.warn("Warning: Interactive form support is not enabled");
|
console.warn("Warning: Interactive form support is not enabled");
|
||||||
this.fallback(UNSUPPORTED_FEATURES.forms);
|
this.fallback(UNSUPPORTED_FEATURES.forms);
|
||||||
|
@ -59,6 +59,11 @@ const OptionKind = {
|
|||||||
* values below *explicitly* rather than relying on imported types.
|
* values below *explicitly* rather than relying on imported types.
|
||||||
*/
|
*/
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
|
annotationMode: {
|
||||||
|
/** @type {number} */
|
||||||
|
value: 2,
|
||||||
|
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||||
|
},
|
||||||
cursorToolOnLoad: {
|
cursorToolOnLoad: {
|
||||||
/** @type {number} */
|
/** @type {number} */
|
||||||
value: 0,
|
value: 0,
|
||||||
@ -145,11 +150,6 @@ const defaultOptions = {
|
|||||||
value: "canvas",
|
value: "canvas",
|
||||||
kind: OptionKind.VIEWER,
|
kind: OptionKind.VIEWER,
|
||||||
},
|
},
|
||||||
renderInteractiveForms: {
|
|
||||||
/** @type {boolean} */
|
|
||||||
value: true,
|
|
||||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
|
||||||
},
|
|
||||||
sidebarViewOnLoad: {
|
sidebarViewOnLoad: {
|
||||||
/** @type {number} */
|
/** @type {number} */
|
||||||
value: -1,
|
value: -1,
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createPromiseCapability, version } from "pdfjs-lib";
|
import { AnnotationMode, createPromiseCapability, version } from "pdfjs-lib";
|
||||||
import {
|
import {
|
||||||
CSS_UNITS,
|
CSS_UNITS,
|
||||||
DEFAULT_SCALE,
|
DEFAULT_SCALE,
|
||||||
@ -67,10 +67,13 @@ const DEFAULT_CACHE_SIZE = 10;
|
|||||||
* selection and searching is created, and if the improved text selection
|
* selection and searching is created, and if the improved text selection
|
||||||
* behaviour is enabled. The constants from {TextLayerMode} should be used.
|
* behaviour is enabled. The constants from {TextLayerMode} should be used.
|
||||||
* The default value is `TextLayerMode.ENABLE`.
|
* 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
|
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||||
* mainly for annotation icons. Include trailing slash.
|
* 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
|
* @property {boolean} [enablePrintAutoRotate] - Enables automatic rotation of
|
||||||
* landscape pages upon printing. The default is `false`.
|
* landscape pages upon printing. The default is `false`.
|
||||||
* @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'.
|
* @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'.
|
||||||
@ -182,11 +185,10 @@ class BaseViewer {
|
|||||||
this.findController = options.findController || null;
|
this.findController = options.findController || null;
|
||||||
this._scriptingManager = options.scriptingManager || null;
|
this._scriptingManager = options.scriptingManager || null;
|
||||||
this.removePageBorders = options.removePageBorders || false;
|
this.removePageBorders = options.removePageBorders || false;
|
||||||
this.textLayerMode = Number.isInteger(options.textLayerMode)
|
this.textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE;
|
||||||
? options.textLayerMode
|
this._annotationMode =
|
||||||
: TextLayerMode.ENABLE;
|
options.annotationMode ?? AnnotationMode.ENABLE_FORMS;
|
||||||
this.imageResourcesPath = options.imageResourcesPath || "";
|
this.imageResourcesPath = options.imageResourcesPath || "";
|
||||||
this.renderInteractiveForms = options.renderInteractiveForms !== false;
|
|
||||||
this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;
|
this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;
|
||||||
this.renderer = options.renderer || RendererType.CANVAS;
|
this.renderer = options.renderer || RendererType.CANVAS;
|
||||||
this.useOnlyCssZoom = options.useOnlyCssZoom || false;
|
this.useOnlyCssZoom = options.useOnlyCssZoom || false;
|
||||||
@ -240,6 +242,13 @@ class BaseViewer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
get renderForms() {
|
||||||
|
return this._annotationMode === AnnotationMode.ENABLE_FORMS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
@ -529,6 +538,8 @@ class BaseViewer {
|
|||||||
this.textLayerMode !== TextLayerMode.DISABLE && !isPureXfa
|
this.textLayerMode !== TextLayerMode.DISABLE && !isPureXfa
|
||||||
? this
|
? this
|
||||||
: null;
|
: null;
|
||||||
|
const annotationLayerFactory =
|
||||||
|
this._annotationMode !== AnnotationMode.DISABLE ? this : null;
|
||||||
const xfaLayerFactory = isPureXfa ? this : null;
|
const xfaLayerFactory = isPureXfa ? this : null;
|
||||||
|
|
||||||
for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
|
for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {
|
||||||
@ -542,12 +553,12 @@ class BaseViewer {
|
|||||||
renderingQueue: this.renderingQueue,
|
renderingQueue: this.renderingQueue,
|
||||||
textLayerFactory,
|
textLayerFactory,
|
||||||
textLayerMode: this.textLayerMode,
|
textLayerMode: this.textLayerMode,
|
||||||
annotationLayerFactory: this,
|
annotationLayerFactory,
|
||||||
|
annotationMode: this._annotationMode,
|
||||||
xfaLayerFactory,
|
xfaLayerFactory,
|
||||||
textHighlighterFactory: this,
|
textHighlighterFactory: this,
|
||||||
structTreeLayerFactory: this,
|
structTreeLayerFactory: this,
|
||||||
imageResourcesPath: this.imageResourcesPath,
|
imageResourcesPath: this.imageResourcesPath,
|
||||||
renderInteractiveForms: this.renderInteractiveForms,
|
|
||||||
renderer: this.renderer,
|
renderer: this.renderer,
|
||||||
useOnlyCssZoom: this.useOnlyCssZoom,
|
useOnlyCssZoom: this.useOnlyCssZoom,
|
||||||
maxCanvasPixels: this.maxCanvasPixels,
|
maxCanvasPixels: this.maxCanvasPixels,
|
||||||
@ -1289,7 +1300,7 @@ class BaseViewer {
|
|||||||
* data in forms.
|
* data in forms.
|
||||||
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
||||||
* for annotation icons. Include trailing slash.
|
* for annotation icons. Include trailing slash.
|
||||||
* @param {boolean} renderInteractiveForms
|
* @param {boolean} renderForms
|
||||||
* @param {IL10n} l10n
|
* @param {IL10n} l10n
|
||||||
* @param {boolean} [enableScripting]
|
* @param {boolean} [enableScripting]
|
||||||
* @param {Promise<boolean>} [hasJSActionsPromise]
|
* @param {Promise<boolean>} [hasJSActionsPromise]
|
||||||
@ -1301,7 +1312,7 @@ class BaseViewer {
|
|||||||
pdfPage,
|
pdfPage,
|
||||||
annotationStorage = null,
|
annotationStorage = null,
|
||||||
imageResourcesPath = "",
|
imageResourcesPath = "",
|
||||||
renderInteractiveForms = false,
|
renderForms = true,
|
||||||
l10n = NullL10n,
|
l10n = NullL10n,
|
||||||
enableScripting = null,
|
enableScripting = null,
|
||||||
hasJSActionsPromise = null,
|
hasJSActionsPromise = null,
|
||||||
@ -1313,7 +1324,7 @@ class BaseViewer {
|
|||||||
annotationStorage:
|
annotationStorage:
|
||||||
annotationStorage || this.pdfDocument?.annotationStorage,
|
annotationStorage || this.pdfDocument?.annotationStorage,
|
||||||
imageResourcesPath,
|
imageResourcesPath,
|
||||||
renderInteractiveForms,
|
renderForms,
|
||||||
linkService: this.linkService,
|
linkService: this.linkService,
|
||||||
downloadManager: this.downloadManager,
|
downloadManager: this.downloadManager,
|
||||||
l10n,
|
l10n,
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { RenderingCancelledException, shadow } from "pdfjs-lib";
|
import { AnnotationMode, RenderingCancelledException, shadow } from "pdfjs-lib";
|
||||||
import { getXfaHtmlForPrinting } from "./print_utils.js";
|
import { getXfaHtmlForPrinting } from "./print_utils.js";
|
||||||
import { PDFPrintServiceFactory } from "./app.js";
|
import { PDFPrintServiceFactory } from "./app.js";
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ function composePage(
|
|||||||
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
|
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
|
||||||
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
|
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
|
||||||
intent: "print",
|
intent: "print",
|
||||||
includeAnnotationStorage: true,
|
annotationMode: AnnotationMode.ENABLE_STORAGE,
|
||||||
optionalContentConfigPromise,
|
optionalContentConfigPromise,
|
||||||
};
|
};
|
||||||
currentRenderTask = thisRenderTask = pdfPage.render(renderContext);
|
currentRenderTask = thisRenderTask = pdfPage.render(renderContext);
|
||||||
|
@ -186,7 +186,7 @@ class IPDFAnnotationLayerFactory {
|
|||||||
* data in forms.
|
* data in forms.
|
||||||
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
* @param {string} [imageResourcesPath] - Path for image resources, mainly
|
||||||
* for annotation icons. Include trailing slash.
|
* for annotation icons. Include trailing slash.
|
||||||
* @param {boolean} renderInteractiveForms
|
* @param {boolean} renderForms
|
||||||
* @param {IL10n} l10n
|
* @param {IL10n} l10n
|
||||||
* @param {boolean} [enableScripting]
|
* @param {boolean} [enableScripting]
|
||||||
* @param {Promise<boolean>} [hasJSActionsPromise]
|
* @param {Promise<boolean>} [hasJSActionsPromise]
|
||||||
@ -198,7 +198,7 @@ class IPDFAnnotationLayerFactory {
|
|||||||
pdfPage,
|
pdfPage,
|
||||||
annotationStorage = null,
|
annotationStorage = null,
|
||||||
imageResourcesPath = "",
|
imageResourcesPath = "",
|
||||||
renderInteractiveForms = true,
|
renderForms = true,
|
||||||
l10n = undefined,
|
l10n = undefined,
|
||||||
enableScripting = false,
|
enableScripting = false,
|
||||||
hasJSActionsPromise = null,
|
hasJSActionsPromise = null,
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
AnnotationMode,
|
||||||
|
createPromiseCapability,
|
||||||
|
RenderingCancelledException,
|
||||||
|
SVGGraphics,
|
||||||
|
} from "pdfjs-lib";
|
||||||
import {
|
import {
|
||||||
approximateFraction,
|
approximateFraction,
|
||||||
CSS_UNITS,
|
CSS_UNITS,
|
||||||
@ -22,11 +28,6 @@ import {
|
|||||||
roundToDivide,
|
roundToDivide,
|
||||||
TextLayerMode,
|
TextLayerMode,
|
||||||
} from "./ui_utils.js";
|
} from "./ui_utils.js";
|
||||||
import {
|
|
||||||
createPromiseCapability,
|
|
||||||
RenderingCancelledException,
|
|
||||||
SVGGraphics,
|
|
||||||
} from "pdfjs-lib";
|
|
||||||
import { compatibilityParams } from "./app_options.js";
|
import { compatibilityParams } from "./app_options.js";
|
||||||
import { NullL10n } from "./l10n_utils.js";
|
import { NullL10n } from "./l10n_utils.js";
|
||||||
import { RenderingStates } from "./pdf_rendering_queue.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
|
* selection and searching is created, and if the improved text selection
|
||||||
* behaviour is enabled. The constants from {TextLayerMode} should be used.
|
* behaviour is enabled. The constants from {TextLayerMode} should be used.
|
||||||
* The default value is `TextLayerMode.ENABLE`.
|
* 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 {IPDFAnnotationLayerFactory} annotationLayerFactory
|
||||||
* @property {IPDFXfaLayerFactory} xfaLayerFactory
|
* @property {IPDFXfaLayerFactory} xfaLayerFactory
|
||||||
* @property {IPDFStructTreeLayerFactory} structTreeLayerFactory
|
* @property {IPDFStructTreeLayerFactory} structTreeLayerFactory
|
||||||
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
* @property {string} [imageResourcesPath] - Path for image resources, mainly
|
||||||
* for annotation icons. Include trailing slash.
|
* 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 {string} renderer - 'canvas' or 'svg'. The default is 'canvas'.
|
||||||
* @property {boolean} [useOnlyCssZoom] - Enables CSS only zooming. The default
|
* @property {boolean} [useOnlyCssZoom] - Enables CSS only zooming. The default
|
||||||
* value is `false`.
|
* value is `false`.
|
||||||
@ -88,11 +92,10 @@ class PDFPageView {
|
|||||||
this._optionalContentConfigPromise =
|
this._optionalContentConfigPromise =
|
||||||
options.optionalContentConfigPromise || null;
|
options.optionalContentConfigPromise || null;
|
||||||
this.hasRestrictedScaling = false;
|
this.hasRestrictedScaling = false;
|
||||||
this.textLayerMode = Number.isInteger(options.textLayerMode)
|
this.textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE;
|
||||||
? options.textLayerMode
|
this._annotationMode =
|
||||||
: TextLayerMode.ENABLE;
|
options.annotationMode ?? AnnotationMode.ENABLE_FORMS;
|
||||||
this.imageResourcesPath = options.imageResourcesPath || "";
|
this.imageResourcesPath = options.imageResourcesPath || "";
|
||||||
this.renderInteractiveForms = options.renderInteractiveForms !== false;
|
|
||||||
this.useOnlyCssZoom = options.useOnlyCssZoom || false;
|
this.useOnlyCssZoom = options.useOnlyCssZoom || false;
|
||||||
this.maxCanvasPixels = options.maxCanvasPixels || MAX_CANVAS_PIXELS;
|
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) {
|
if (!this.annotationLayer) {
|
||||||
this.annotationLayer =
|
this.annotationLayer =
|
||||||
this.annotationLayerFactory.createAnnotationLayerBuilder(
|
this.annotationLayerFactory.createAnnotationLayerBuilder(
|
||||||
@ -646,9 +652,9 @@ class PDFPageView {
|
|||||||
pdfPage,
|
pdfPage,
|
||||||
/* annotationStorage = */ null,
|
/* annotationStorage = */ null,
|
||||||
this.imageResourcesPath,
|
this.imageResourcesPath,
|
||||||
this.renderInteractiveForms,
|
this._annotationMode === AnnotationMode.ENABLE_FORMS,
|
||||||
this.l10n,
|
this.l10n,
|
||||||
/* enableScripting */ null,
|
/* enableScripting = */ null,
|
||||||
/* hasJSActionsPromise = */ null,
|
/* hasJSActionsPromise = */ null,
|
||||||
/* mouseState = */ null
|
/* mouseState = */ null
|
||||||
);
|
);
|
||||||
@ -787,7 +793,7 @@ class PDFPageView {
|
|||||||
canvasContext: ctx,
|
canvasContext: ctx,
|
||||||
transform,
|
transform,
|
||||||
viewport: this.viewport,
|
viewport: this.viewport,
|
||||||
renderInteractiveForms: this.renderInteractiveForms,
|
annotationMode: this._annotationMode,
|
||||||
optionalContentConfigPromise: this._optionalContentConfigPromise,
|
optionalContentConfigPromise: this._optionalContentConfigPromise,
|
||||||
};
|
};
|
||||||
const renderTask = this.pdfPage.render(renderContext);
|
const renderTask = this.pdfPage.render(renderContext);
|
||||||
@ -839,24 +845,28 @@ class PDFPageView {
|
|||||||
|
|
||||||
const pdfPage = this.pdfPage;
|
const pdfPage = this.pdfPage;
|
||||||
const actualSizeViewport = this.viewport.clone({ scale: CSS_UNITS });
|
const actualSizeViewport = this.viewport.clone({ scale: CSS_UNITS });
|
||||||
const promise = pdfPage.getOperatorList().then(opList => {
|
const promise = pdfPage
|
||||||
ensureNotCancelled();
|
.getOperatorList({
|
||||||
const svgGfx = new SVGGraphics(
|
annotationMode: this._annotatationMode,
|
||||||
pdfPage.commonObjs,
|
})
|
||||||
pdfPage.objs,
|
.then(opList => {
|
||||||
/* forceDataSchema = */ compatibilityParams.disableCreateObjectURL
|
|
||||||
);
|
|
||||||
return svgGfx.getSVG(opList, actualSizeViewport).then(svg => {
|
|
||||||
ensureNotCancelled();
|
ensureNotCancelled();
|
||||||
this.svg = svg;
|
const svgGfx = new SVGGraphics(
|
||||||
this.paintedViewportMap.set(svg, actualSizeViewport);
|
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.width = wrapper.style.width;
|
||||||
svg.style.height = wrapper.style.height;
|
svg.style.height = wrapper.style.height;
|
||||||
this.renderingState = RenderingStates.FINISHED;
|
this.renderingState = RenderingStates.FINISHED;
|
||||||
wrapper.appendChild(svg);
|
wrapper.appendChild(svg);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
promise,
|
promise,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { PDFPrintServiceFactory, PDFViewerApplication } from "./app.js";
|
import { PDFPrintServiceFactory, PDFViewerApplication } from "./app.js";
|
||||||
|
import { AnnotationMode } from "pdfjs-lib";
|
||||||
import { compatibilityParams } from "./app_options.js";
|
import { compatibilityParams } from "./app_options.js";
|
||||||
import { getXfaHtmlForPrinting } from "./print_utils.js";
|
import { getXfaHtmlForPrinting } from "./print_utils.js";
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ function renderPage(
|
|||||||
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
|
transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
|
||||||
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
|
viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
|
||||||
intent: "print",
|
intent: "print",
|
||||||
includeAnnotationStorage: true,
|
annotationMode: AnnotationMode.ENABLE_STORAGE,
|
||||||
optionalContentConfigPromise,
|
optionalContentConfigPromise,
|
||||||
};
|
};
|
||||||
return pdfPage.render(renderContext).promise;
|
return pdfPage.render(renderContext).promise;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user