Skip to content

Commit bb81f40

Browse files
Merge pull request #13923 from Snuffleupagus/AnnotationMode
[api-minor] Introduce a new `annotationMode`-option, in `PDFPageProxy.{render, getOperatorList}`
2 parents 56e7bb6 + 2a0ad8e commit bb81f40

16 files changed

+300
-135
lines changed

extensions/chromium/preferences_schema.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,15 @@
144144
"description": "Whether to prevent the extension from reporting the extension and browser version to the extension developers.",
145145
"default": false
146146
},
147-
"renderInteractiveForms": {
148-
"type": "boolean",
149-
"default": true
147+
"annotationMode": {
148+
"type": "integer",
149+
"enum": [
150+
0,
151+
1,
152+
2,
153+
3
154+
],
155+
"default": 2
150156
},
151157
"enableScripting": {
152158
"type": "boolean",

src/core/document.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,10 @@ class Page {
380380
// page's operator list to render them.
381381
return Promise.all([pageListPromise, this._parsedAnnotations]).then(
382382
function ([pageOpList, annotations]) {
383-
if (annotations.length === 0) {
383+
if (
384+
annotations.length === 0 ||
385+
intent & RenderingIntentFlag.ANNOTATIONS_DISABLE
386+
) {
384387
pageOpList.flush(true);
385388
return { length: pageOpList.totalLength };
386389
}

src/display/annotation_layer.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const DEFAULT_TAB_INDEX = 1000;
4646
* @property {AnnotationStorage} [annotationStorage]
4747
* @property {string} [imageResourcesPath] - Path for image resources, mainly
4848
* for annotation icons. Include trailing slash.
49-
* @property {boolean} renderInteractiveForms
49+
* @property {boolean} renderForms
5050
* @property {Object} svgFactory
5151
* @property {boolean} [enableScripting]
5252
* @property {boolean} [hasJSActions]
@@ -154,7 +154,7 @@ class AnnotationElement {
154154
this.linkService = parameters.linkService;
155155
this.downloadManager = parameters.downloadManager;
156156
this.imageResourcesPath = parameters.imageResourcesPath;
157-
this.renderInteractiveForms = parameters.renderInteractiveForms;
157+
this.renderForms = parameters.renderForms;
158158
this.svgFactory = parameters.svgFactory;
159159
this.annotationStorage = parameters.annotationStorage;
160160
this.enableScripting = parameters.enableScripting;
@@ -676,7 +676,7 @@ class WidgetAnnotationElement extends AnnotationElement {
676676
class TextWidgetAnnotationElement extends WidgetAnnotationElement {
677677
constructor(parameters) {
678678
const isRenderable =
679-
parameters.renderInteractiveForms ||
679+
parameters.renderForms ||
680680
(!parameters.data.hasAppearance && !!parameters.data.fieldValue);
681681
super(parameters, { isRenderable });
682682
}
@@ -700,7 +700,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
700700
this.container.className = "textWidgetAnnotation";
701701

702702
let element = null;
703-
if (this.renderInteractiveForms) {
703+
if (this.renderForms) {
704704
// NOTE: We cannot set the values using `element.value` below, since it
705705
// prevents the AnnotationLayer rasterizer in `test/driver.js`
706706
// from parsing the elements correctly for the reference tests.
@@ -952,7 +952,7 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
952952

953953
class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
954954
constructor(parameters) {
955-
super(parameters, { isRenderable: parameters.renderInteractiveForms });
955+
super(parameters, { isRenderable: parameters.renderForms });
956956
}
957957

958958
render() {
@@ -1031,7 +1031,7 @@ class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement {
10311031

10321032
class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement {
10331033
constructor(parameters) {
1034-
super(parameters, { isRenderable: parameters.renderInteractiveForms });
1034+
super(parameters, { isRenderable: parameters.renderForms });
10351035
}
10361036

10371037
render() {
@@ -1123,7 +1123,7 @@ class PushButtonWidgetAnnotationElement extends LinkAnnotationElement {
11231123

11241124
class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
11251125
constructor(parameters) {
1126-
super(parameters, { isRenderable: parameters.renderInteractiveForms });
1126+
super(parameters, { isRenderable: parameters.renderForms });
11271127
}
11281128

11291129
render() {
@@ -2033,7 +2033,7 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
20332033
* @property {DownloadManager} downloadManager
20342034
* @property {string} [imageResourcesPath] - Path for image resources, mainly
20352035
* for annotation icons. Include trailing slash.
2036-
* @property {boolean} renderInteractiveForms
2036+
* @property {boolean} renderForms
20372037
* @property {boolean} [enableScripting] - Enable embedded script execution.
20382038
* @property {boolean} [hasJSActions] - Some fields have JS actions.
20392039
* The default value is `false`.
@@ -2076,7 +2076,7 @@ class AnnotationLayer {
20762076
linkService: parameters.linkService,
20772077
downloadManager: parameters.downloadManager,
20782078
imageResourcesPath: parameters.imageResourcesPath || "",
2079-
renderInteractiveForms: parameters.renderInteractiveForms !== false,
2079+
renderForms: parameters.renderForms !== false,
20802080
svgFactory: new DOMSVGFactory(),
20812081
annotationStorage:
20822082
parameters.annotationStorage || new AnnotationStorage(),

src/display/api.js

Lines changed: 85 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import {
2121
AbortException,
22+
AnnotationMode,
2223
assert,
2324
createPromiseCapability,
2425
getVerbosityLevel,
@@ -1135,9 +1136,18 @@ class PDFDocumentProxy {
11351136
* the `PDFPageProxy.getViewport` method.
11361137
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
11371138
* or 'any'. The default value is 'display'.
1138-
* @property {boolean} [renderInteractiveForms] - Whether or not interactive
1139-
* form elements are rendered in the display layer. If so, we do not render
1140-
* them on the canvas as well. The default value is `false`.
1139+
* @property {number} [annotationMode] Controls which annotations are rendered
1140+
* onto the canvas, for annotations with appearance-data; the values from
1141+
* {@link AnnotationMode} should be used. The following values are supported:
1142+
* - `AnnotationMode.DISABLE`, which disables all annotations.
1143+
* - `AnnotationMode.ENABLE`, which includes all possible annotations (thus
1144+
* it also depends on the `intent`-option, see above).
1145+
* - `AnnotationMode.ENABLE_FORMS`, which excludes annotations that contain
1146+
* interactive form elements (those will be rendered in the display layer).
1147+
* - `AnnotationMode.ENABLE_STORAGE`, which includes all possible annotations
1148+
* (as above) but where interactive form elements are updated with data
1149+
* from the {@link AnnotationStorage}-instance; useful e.g. for printing.
1150+
* The default value is `AnnotationMode.ENABLE`.
11411151
* @property {Array<any>} [transform] - Additional transform, applied just
11421152
* before viewport transform.
11431153
* @property {Object} [imageLayer] - An object that has `beginLayout`,
@@ -1149,9 +1159,6 @@ class PDFDocumentProxy {
11491159
* <color> value, a `CanvasGradient` object (a linear or radial gradient) or
11501160
* a `CanvasPattern` object (a repetitive image). The default value is
11511161
* 'rgb(255,255,255)'.
1152-
* @property {boolean} [includeAnnotationStorage] - Render stored interactive
1153-
* form element data, from the {@link AnnotationStorage}-instance, onto the
1154-
* canvas itself; useful e.g. for printing. The default value is `false`.
11551162
* @property {Promise<OptionalContentConfig>} [optionalContentConfigPromise] -
11561163
* A promise that should resolve with an {@link OptionalContentConfig}
11571164
* created from `PDFDocumentProxy.getOptionalContentConfig`. If `null`,
@@ -1165,6 +1172,18 @@ class PDFDocumentProxy {
11651172
* @typedef {Object} GetOperatorListParameters
11661173
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
11671174
* or 'any'. The default value is 'display'.
1175+
* @property {number} [annotationMode] Controls which annotations are included
1176+
* in the operatorList, for annotations with appearance-data; the values from
1177+
* {@link AnnotationMode} should be used. The following values are supported:
1178+
* - `AnnotationMode.DISABLE`, which disables all annotations.
1179+
* - `AnnotationMode.ENABLE`, which includes all possible annotations (thus
1180+
* it also depends on the `intent`-option, see above).
1181+
* - `AnnotationMode.ENABLE_FORMS`, which excludes annotations that contain
1182+
* interactive form elements (those will be rendered in the display layer).
1183+
* - `AnnotationMode.ENABLE_STORAGE`, which includes all possible annotations
1184+
* (as above) but where interactive form elements are updated with data
1185+
* from the {@link AnnotationStorage}-instance; useful e.g. for printing.
1186+
* The default value is `AnnotationMode.ENABLE`.
11681187
*/
11691188

11701189
/**
@@ -1280,7 +1299,7 @@ class PDFPageProxy {
12801299
* {Array} of the annotation objects.
12811300
*/
12821301
getAnnotations({ intent = "display" } = {}) {
1283-
const intentArgs = this._transport.getRenderingIntent(intent, {});
1302+
const intentArgs = this._transport.getRenderingIntent(intent);
12841303

12851304
let promise = this._annotationPromises.get(intentArgs.cacheKey);
12861305
if (!promise) {
@@ -1324,22 +1343,48 @@ class PDFPageProxy {
13241343
canvasContext,
13251344
viewport,
13261345
intent = "display",
1327-
renderInteractiveForms = false,
1346+
annotationMode = AnnotationMode.ENABLE,
13281347
transform = null,
13291348
imageLayer = null,
13301349
canvasFactory = null,
13311350
background = null,
1332-
includeAnnotationStorage = false,
13331351
optionalContentConfigPromise = null,
13341352
}) {
1353+
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC")) {
1354+
if (arguments[0]?.renderInteractiveForms !== undefined) {
1355+
deprecated(
1356+
"render no longer accepts the `renderInteractiveForms`-option, " +
1357+
"please use the `annotationMode`-option instead."
1358+
);
1359+
if (
1360+
arguments[0].renderInteractiveForms === true &&
1361+
annotationMode === AnnotationMode.ENABLE
1362+
) {
1363+
annotationMode = AnnotationMode.ENABLE_FORMS;
1364+
}
1365+
}
1366+
if (arguments[0]?.includeAnnotationStorage !== undefined) {
1367+
deprecated(
1368+
"render no longer accepts the `includeAnnotationStorage`-option, " +
1369+
"please use the `annotationMode`-option instead."
1370+
);
1371+
if (
1372+
arguments[0].includeAnnotationStorage === true &&
1373+
annotationMode === AnnotationMode.ENABLE
1374+
) {
1375+
annotationMode = AnnotationMode.ENABLE_STORAGE;
1376+
}
1377+
}
1378+
}
1379+
13351380
if (this._stats) {
13361381
this._stats.time("Overall");
13371382
}
13381383

1339-
const intentArgs = this._transport.getRenderingIntent(intent, {
1340-
renderForms: renderInteractiveForms === true,
1341-
includeAnnotationStorage: includeAnnotationStorage === true,
1342-
});
1384+
const intentArgs = this._transport.getRenderingIntent(
1385+
intent,
1386+
annotationMode
1387+
);
13431388
// If there was a pending destroy, cancel it so no cleanup happens during
13441389
// this call to render.
13451390
this.pendingCleanup = false;
@@ -1460,7 +1505,10 @@ class PDFPageProxy {
14601505
* @returns {Promise<PDFOperatorList>} A promise resolved with an
14611506
* {@link PDFOperatorList} object that represents the page's operator list.
14621507
*/
1463-
getOperatorList({ intent = "display" } = {}) {
1508+
getOperatorList({
1509+
intent = "display",
1510+
annotationMode = AnnotationMode.ENABLE,
1511+
} = {}) {
14641512
function operatorListChanged() {
14651513
if (intentState.operatorList.lastChunk) {
14661514
intentState.opListReadCapability.resolve(intentState.operatorList);
@@ -1469,9 +1517,11 @@ class PDFPageProxy {
14691517
}
14701518
}
14711519

1472-
const intentArgs = this._transport.getRenderingIntent(intent, {
1473-
isOpList: true,
1474-
});
1520+
const intentArgs = this._transport.getRenderingIntent(
1521+
intent,
1522+
annotationMode,
1523+
/* isOpList = */ true
1524+
);
14751525
let intentState = this._intentStates.get(intentArgs.cacheKey);
14761526
if (!intentState) {
14771527
intentState = Object.create(null);
@@ -1792,7 +1842,7 @@ class PDFPageProxy {
17921842
}
17931843
}
17941844
intentState.streamReader
1795-
.cancel(new AbortException(reason?.message))
1845+
.cancel(new AbortException(reason.message))
17961846
.catch(() => {
17971847
// Avoid "Uncaught promise" messages in the console.
17981848
});
@@ -2351,7 +2401,8 @@ class WorkerTransport {
23512401

23522402
getRenderingIntent(
23532403
intent,
2354-
{ renderForms = false, includeAnnotationStorage = false, isOpList = false }
2404+
annotationMode = AnnotationMode.ENABLE,
2405+
isOpList = false
23552406
) {
23562407
let renderingIntent = RenderingIntentFlag.DISPLAY; // Default value.
23572408
let lastModified = "";
@@ -2369,13 +2420,22 @@ class WorkerTransport {
23692420
warn(`getRenderingIntent - invalid intent: ${intent}`);
23702421
}
23712422

2372-
if (renderForms) {
2373-
renderingIntent += RenderingIntentFlag.ANNOTATIONS_FORMS;
2374-
}
2375-
if (includeAnnotationStorage) {
2376-
renderingIntent += RenderingIntentFlag.ANNOTATIONS_STORAGE;
2423+
switch (annotationMode) {
2424+
case AnnotationMode.DISABLE:
2425+
renderingIntent += RenderingIntentFlag.ANNOTATIONS_DISABLE;
2426+
break;
2427+
case AnnotationMode.ENABLE:
2428+
break;
2429+
case AnnotationMode.ENABLE_FORMS:
2430+
renderingIntent += RenderingIntentFlag.ANNOTATIONS_FORMS;
2431+
break;
2432+
case AnnotationMode.ENABLE_STORAGE:
2433+
renderingIntent += RenderingIntentFlag.ANNOTATIONS_STORAGE;
23772434

2378-
lastModified = this.annotationStorage.lastModified;
2435+
lastModified = this.annotationStorage.lastModified;
2436+
break;
2437+
default:
2438+
warn(`getRenderingIntent - invalid annotationMode: ${annotationMode}`);
23792439
}
23802440

23812441
if (isOpList) {

src/pdf.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,7 @@ import {
2727
RenderingCancelledException,
2828
} from "./display/display_utils.js";
2929
import {
30-
build,
31-
getDocument,
32-
LoopbackPort,
33-
PDFDataRangeTransport,
34-
PDFWorker,
35-
setPDFNetworkStreamFactory,
36-
version,
37-
} from "./display/api.js";
38-
import {
30+
AnnotationMode,
3931
CMapCompressionType,
4032
createObjectURL,
4133
createPromiseCapability,
@@ -52,6 +44,15 @@ import {
5244
Util,
5345
VerbosityLevel,
5446
} from "./shared/util.js";
47+
import {
48+
build,
49+
getDocument,
50+
LoopbackPort,
51+
PDFDataRangeTransport,
52+
PDFWorker,
53+
setPDFNetworkStreamFactory,
54+
version,
55+
} from "./display/api.js";
5556
import { AnnotationLayer } from "./display/annotation_layer.js";
5657
import { GlobalWorkerOptions } from "./display/worker_options.js";
5758
import { isNodeJS } from "./shared/is_node.js";
@@ -110,14 +111,8 @@ export {
110111
PDFDateString,
111112
RenderingCancelledException,
112113
getXfaPageViewport,
113-
// From "./display/api.js":
114-
build,
115-
getDocument,
116-
LoopbackPort,
117-
PDFDataRangeTransport,
118-
PDFWorker,
119-
version,
120114
// From "./shared/util.js":
115+
AnnotationMode,
121116
CMapCompressionType,
122117
createObjectURL,
123118
createPromiseCapability,
@@ -133,6 +128,13 @@ export {
133128
UNSUPPORTED_FEATURES,
134129
Util,
135130
VerbosityLevel,
131+
// From "./display/api.js":
132+
build,
133+
getDocument,
134+
LoopbackPort,
135+
PDFDataRangeTransport,
136+
PDFWorker,
137+
version,
136138
// From "./display/annotation_layer.js":
137139
AnnotationLayer,
138140
// From "./display/worker_options.js":

0 commit comments

Comments
 (0)