Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[api-minor] Improve thumbnail handling in documents that contain interactive forms #15246

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions src/core/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,11 @@ class Annotation {
);
if (!appearance) {
if (!isUsingOwnCanvas) {
return new OperatorList();
return {
opList: new OperatorList(),
separateForm: false,
separateCanvas: false,
};
}
appearance = new StringStream("");
appearance.dict = new Dict();
Expand Down Expand Up @@ -930,7 +934,7 @@ class Annotation {
opList.addOp(OPS.endMarkedContent, []);
}
this.reset();
return opList;
return { opList, separateForm: false, separateCanvas: isUsingOwnCanvas };
}

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

if (!this._hasText) {
Expand Down Expand Up @@ -1647,12 +1655,12 @@ class WidgetAnnotation extends Annotation {
);
}

const operatorList = new OperatorList();
const opList = new OperatorList();

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

const matrix = [1, 0, 0, 1, 0, 0];
Expand All @@ -1672,10 +1680,10 @@ class WidgetAnnotation extends Annotation {
);
}
if (optionalContent !== undefined) {
operatorList.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
opList.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
}

operatorList.addOp(OPS.beginAnnotation, [
opList.addOp(OPS.beginAnnotation, [
this.data.id,
this.data.rect,
transform,
Expand All @@ -1688,14 +1696,14 @@ class WidgetAnnotation extends Annotation {
stream,
task,
resources: this._fieldResources.mergedResources,
operatorList,
operatorList: opList,
});
operatorList.addOp(OPS.endAnnotation, []);
opList.addOp(OPS.endAnnotation, []);

if (optionalContent !== undefined) {
operatorList.addOp(OPS.endMarkedContent, []);
opList.addOp(OPS.endMarkedContent, []);
}
return operatorList;
return { opList, separateForm: false, separateCanvas: false };
}

_getMKDict(rotation) {
Expand Down Expand Up @@ -2477,7 +2485,11 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
}

// No appearance
return new OperatorList();
return {
opList: new OperatorList(),
separateForm: false,
separateCanvas: false,
};
}

async save(evaluator, task, annotationStorage) {
Expand Down
19 changes: 16 additions & 3 deletions src/core/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ class Page {
annotations.length === 0 ||
intent & RenderingIntentFlag.ANNOTATIONS_DISABLE
) {
pageOpList.flush(true);
pageOpList.flush(/* lastChunk = */ true);
return { length: pageOpList.totalLength };
}
const renderForms = !!(intent & RenderingIntentFlag.ANNOTATIONS_FORMS),
Expand Down Expand Up @@ -493,10 +493,23 @@ class Page {
}

return Promise.all(opListPromises).then(function (opLists) {
for (const opList of opLists) {
let form = false,
canvas = false;

for (const { opList, separateForm, separateCanvas } of opLists) {
pageOpList.addOpList(opList);

if (separateForm) {
form = separateForm;
}
if (separateCanvas) {
canvas = separateCanvas;
}
}
pageOpList.flush(true);
pageOpList.flush(
/* lastChunk = */ true,
/* separateAnnots = */ { form, canvas }
);
return { length: pageOpList.totalLength };
});
});
Expand Down
3 changes: 2 additions & 1 deletion src/core/operator_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ class OperatorList {
return transfers;
}

flush(lastChunk = false) {
flush(lastChunk = false, separateAnnots = null) {
this.optimizer.flush();
const length = this.length;
this._totalLength += length;
Expand All @@ -700,6 +700,7 @@ class OperatorList {
fnArray: this.fnArray,
argsArray: this.argsArray,
lastChunk,
separateAnnots,
length,
},
1,
Expand Down
27 changes: 24 additions & 3 deletions src/display/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,7 @@ class PDFPageProxy {
fnArray: [],
argsArray: [],
lastChunk: false,
separateAnnots: null,
};

if (this._stats) {
Expand Down Expand Up @@ -1599,6 +1600,7 @@ class PDFPageProxy {
fnArray: [],
argsArray: [],
lastChunk: false,
separateAnnots: null,
};

if (this._stats) {
Expand Down Expand Up @@ -1795,6 +1797,7 @@ class PDFPageProxy {
intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]);
}
intentState.operatorList.lastChunk = operatorListChunk.lastChunk;
intentState.operatorList.separateAnnots = operatorListChunk.separateAnnots;

// Notify all the rendering tasks there are more operators to be consumed.
for (const internalRenderTask of intentState.renderTasks) {
Expand Down Expand Up @@ -3194,8 +3197,10 @@ class PDFObjects {
* Allows controlling of the rendering tasks.
*/
class RenderTask {
#internalRenderTask = null;

constructor(internalRenderTask) {
this._internalRenderTask = internalRenderTask;
this.#internalRenderTask = internalRenderTask;

/**
* Callback for incremental rendering -- a function that will be called
Expand All @@ -3211,7 +3216,7 @@ class RenderTask {
* @type {Promise<void>}
*/
get promise() {
return this._internalRenderTask.capability.promise;
return this.#internalRenderTask.capability.promise;
}

/**
Expand All @@ -3220,7 +3225,23 @@ class RenderTask {
* this object extends will be rejected when cancelled.
*/
cancel() {
this._internalRenderTask.cancel();
this.#internalRenderTask.cancel();
}

/**
* Whether form fields are rendered separately from the main operatorList.
* @type {boolean}
*/
get separateAnnots() {
const { separateAnnots } = this.#internalRenderTask.operatorList;
if (!separateAnnots) {
return false;
}
const { annotationCanvasMap } = this.#internalRenderTask;
return (
separateAnnots.form ||
(separateAnnots.canvas && annotationCanvasMap?.size > 0)
);
}
}

Expand Down
Loading