Skip to content

Commit b8aa9c6

Browse files
Merge pull request #15246 from Snuffleupagus/thumbnail-setImage-improvements
[api-minor] Improve `thumbnail` handling in documents that contain interactive forms
2 parents 77b3489 + 0c31320 commit b8aa9c6

File tree

7 files changed

+185
-101
lines changed

7 files changed

+185
-101
lines changed

src/core/annotation.js

+24-12
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,11 @@ class Annotation {
881881
);
882882
if (!appearance) {
883883
if (!isUsingOwnCanvas) {
884-
return new OperatorList();
884+
return {
885+
opList: new OperatorList(),
886+
separateForm: false,
887+
separateCanvas: false,
888+
};
885889
}
886890
appearance = new StringStream("");
887891
appearance.dict = new Dict();
@@ -930,7 +934,7 @@ class Annotation {
930934
opList.addOp(OPS.endMarkedContent, []);
931935
}
932936
this.reset();
933-
return opList;
937+
return { opList, separateForm: false, separateCanvas: isUsingOwnCanvas };
934938
}
935939

936940
async save(evaluator, task, annotationStorage) {
@@ -1619,7 +1623,11 @@ class WidgetAnnotation extends Annotation {
16191623
// Do not render form elements on the canvas when interactive forms are
16201624
// enabled. The display layer is responsible for rendering them instead.
16211625
if (renderForms && !(this instanceof SignatureWidgetAnnotation)) {
1622-
return new OperatorList();
1626+
return {
1627+
opList: new OperatorList(),
1628+
separateForm: true,
1629+
separateCanvas: false,
1630+
};
16231631
}
16241632

16251633
if (!this._hasText) {
@@ -1647,12 +1655,12 @@ class WidgetAnnotation extends Annotation {
16471655
);
16481656
}
16491657

1650-
const operatorList = new OperatorList();
1658+
const opList = new OperatorList();
16511659

16521660
// Even if there is an appearance stream, ignore it. This is the
16531661
// behaviour used by Adobe Reader.
16541662
if (!this._defaultAppearance || content === null) {
1655-
return operatorList;
1663+
return { opList, separateForm: false, separateCanvas: false };
16561664
}
16571665

16581666
const matrix = [1, 0, 0, 1, 0, 0];
@@ -1672,10 +1680,10 @@ class WidgetAnnotation extends Annotation {
16721680
);
16731681
}
16741682
if (optionalContent !== undefined) {
1675-
operatorList.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
1683+
opList.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
16761684
}
16771685

1678-
operatorList.addOp(OPS.beginAnnotation, [
1686+
opList.addOp(OPS.beginAnnotation, [
16791687
this.data.id,
16801688
this.data.rect,
16811689
transform,
@@ -1688,14 +1696,14 @@ class WidgetAnnotation extends Annotation {
16881696
stream,
16891697
task,
16901698
resources: this._fieldResources.mergedResources,
1691-
operatorList,
1699+
operatorList: opList,
16921700
});
1693-
operatorList.addOp(OPS.endAnnotation, []);
1701+
opList.addOp(OPS.endAnnotation, []);
16941702

16951703
if (optionalContent !== undefined) {
1696-
operatorList.addOp(OPS.endMarkedContent, []);
1704+
opList.addOp(OPS.endMarkedContent, []);
16971705
}
1698-
return operatorList;
1706+
return { opList, separateForm: false, separateCanvas: false };
16991707
}
17001708

17011709
_getMKDict(rotation) {
@@ -2477,7 +2485,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
24772485
}
24782486

24792487
// No appearance
2480-
return new OperatorList();
2488+
return {
2489+
opList: new OperatorList(),
2490+
separateForm: false,
2491+
separateCanvas: false,
2492+
};
24812493
}
24822494

24832495
async save(evaluator, task, annotationStorage) {

src/core/document.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ class Page {
455455
annotations.length === 0 ||
456456
intent & RenderingIntentFlag.ANNOTATIONS_DISABLE
457457
) {
458-
pageOpList.flush(true);
458+
pageOpList.flush(/* lastChunk = */ true);
459459
return { length: pageOpList.totalLength };
460460
}
461461
const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS),
@@ -493,10 +493,23 @@ class Page {
493493
}
494494

495495
return Promise.all(opListPromises).then(function (opLists) {
496-
for (const opList of opLists) {
496+
let form = false,
497+
canvas = false;
498+
499+
for (const { opList, separateForm, separateCanvas } of opLists) {
497500
pageOpList.addOpList(opList);
501+
502+
if (separateForm) {
503+
form = separateForm;
504+
}
505+
if (separateCanvas) {
506+
canvas = separateCanvas;
507+
}
498508
}
499-
pageOpList.flush(true);
509+
pageOpList.flush(
510+
/* lastChunk = */ true,
511+
/* separateAnnots = */ { form, canvas }
512+
);
500513
return { length: pageOpList.totalLength };
501514
});
502515
});

src/core/operator_list.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ class OperatorList {
690690
return transfers;
691691
}
692692

693-
flush(lastChunk = false) {
693+
flush(lastChunk = false, separateAnnots = null) {
694694
this.optimizer.flush();
695695
const length = this.length;
696696
this._totalLength += length;
@@ -700,6 +700,7 @@ class OperatorList {
700700
fnArray: this.fnArray,
701701
argsArray: this.argsArray,
702702
lastChunk,
703+
separateAnnots,
703704
length,
704705
},
705706
1,

src/display/api.js

+24-3
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,7 @@ class PDFPageProxy {
14771477
fnArray: [],
14781478
argsArray: [],
14791479
lastChunk: false,
1480+
separateAnnots: null,
14801481
};
14811482

14821483
if (this._stats) {
@@ -1599,6 +1600,7 @@ class PDFPageProxy {
15991600
fnArray: [],
16001601
argsArray: [],
16011602
lastChunk: false,
1603+
separateAnnots: null,
16021604
};
16031605

16041606
if (this._stats) {
@@ -1795,6 +1797,7 @@ class PDFPageProxy {
17951797
intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]);
17961798
}
17971799
intentState.operatorList.lastChunk = operatorListChunk.lastChunk;
1800+
intentState.operatorList.separateAnnots = operatorListChunk.separateAnnots;
17981801

17991802
// Notify all the rendering tasks there are more operators to be consumed.
18001803
for (const internalRenderTask of intentState.renderTasks) {
@@ -3194,8 +3197,10 @@ class PDFObjects {
31943197
* Allows controlling of the rendering tasks.
31953198
*/
31963199
class RenderTask {
3200+
#internalRenderTask = null;
3201+
31973202
constructor(internalRenderTask) {
3198-
this._internalRenderTask = internalRenderTask;
3203+
this.#internalRenderTask = internalRenderTask;
31993204

32003205
/**
32013206
* Callback for incremental rendering -- a function that will be called
@@ -3211,7 +3216,7 @@ class RenderTask {
32113216
* @type {Promise<void>}
32123217
*/
32133218
get promise() {
3214-
return this._internalRenderTask.capability.promise;
3219+
return this.#internalRenderTask.capability.promise;
32153220
}
32163221

32173222
/**
@@ -3220,7 +3225,23 @@ class RenderTask {
32203225
* this object extends will be rejected when cancelled.
32213226
*/
32223227
cancel() {
3223-
this._internalRenderTask.cancel();
3228+
this.#internalRenderTask.cancel();
3229+
}
3230+
3231+
/**
3232+
* Whether form fields are rendered separately from the main operatorList.
3233+
* @type {boolean}
3234+
*/
3235+
get separateAnnots() {
3236+
const { separateAnnots } = this.#internalRenderTask.operatorList;
3237+
if (!separateAnnots) {
3238+
return false;
3239+
}
3240+
const { annotationCanvasMap } = this.#internalRenderTask;
3241+
return (
3242+
separateAnnots.form ||
3243+
(separateAnnots.canvas && annotationCanvasMap?.size > 0)
3244+
);
32243245
}
32253246
}
32263247

0 commit comments

Comments
 (0)