Merge pull request #13746 from Snuffleupagus/getOperatorList-intent

[api-minor] Add `intent` support to the `PDFPageProxy.getOperatorList` method (issue 13704)
This commit is contained in:
Tim van der Meij 2021-07-18 13:28:08 +02:00 committed by GitHub
commit 668c58d68d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 121 additions and 17 deletions

View File

@ -702,7 +702,13 @@ class Annotation {
return resourcesPromise.then(resources => {
const opList = new OperatorList();
opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]);
opList.addOp(OPS.beginAnnotation, [
data.id,
data.rect,
transform,
matrix,
]);
return evaluator
.getOperatorList({
stream: appearance,
@ -1307,6 +1313,7 @@ class WidgetAnnotation extends Annotation {
const transform = getTransformMatrix(this.data.rect, bbox, matrix);
operatorList.addOp(OPS.beginAnnotation, [
this.data.id,
this.data.rect,
transform,
matrix,

View File

@ -366,12 +366,16 @@ class Page {
// Collect the operator list promises for the annotations. Each promise
// is resolved with the complete operator list for a single annotation.
const annotationIntent = intent.startsWith("oplist-")
? intent.split("-")[1]
: intent;
const opListPromises = [];
for (const annotation of annotations) {
if (
(intent === "display" &&
(annotationIntent === "display" &&
annotation.mustBeViewed(annotationStorage)) ||
(intent === "print" && annotation.mustBePrinted(annotationStorage))
(annotationIntent === "print" &&
annotation.mustBePrinted(annotationStorage))
) {
opListPromises.push(
annotation

View File

@ -594,14 +594,14 @@ class OperatorList {
// Close to chunk size.
static get CHUNK_SIZE_ABOUT() {
return shadow(this, "CHUNK_SIZE_ABOUT", OperatorList.CHUNK_SIZE - 5);
return shadow(this, "CHUNK_SIZE_ABOUT", this.CHUNK_SIZE - 5);
}
constructor(intent, streamSink) {
this._streamSink = streamSink;
this.fnArray = [];
this.argsArray = [];
if (streamSink && intent !== "oplist") {
if (streamSink && !(intent && intent.startsWith("oplist-"))) {
this.optimizer = new QueueOptimizer(this);
} else {
this.optimizer = new NullOptimizer(this);

View File

@ -1149,7 +1149,7 @@ class PDFDocumentProxy {
* Page annotation parameters.
*
* @typedef {Object} GetAnnotationsParameters
* @property {string} intent - Determines the annotations that will be fetched,
* @property {string} [intent] - Determines the annotations that are fetched,
* can be either 'display' (viewable annotations) or 'print' (printable
* annotations). If the parameter is omitted, all annotations are fetched.
*/
@ -1187,6 +1187,14 @@ class PDFDocumentProxy {
* states set.
*/
/**
* Page getOperatorList parameters.
*
* @typedef {Object} GetOperatorListParameters
* @property {string} [intent] - Rendering intent, can be 'display' or 'print'.
* The default value is 'display'.
*/
/**
* Structure tree node. The root node will have a role "Root".
*
@ -1299,12 +1307,18 @@ class PDFPageProxy {
* {Array} of the annotation objects.
*/
getAnnotations({ intent = null } = {}) {
if (!this._annotationsPromise || this._annotationsIntent !== intent) {
const renderingIntent =
intent === "display" || intent === "print" ? intent : null;
if (
!this._annotationsPromise ||
this._annotationsIntent !== renderingIntent
) {
this._annotationsPromise = this._transport.getAnnotations(
this._pageIndex,
intent
renderingIntent
);
this._annotationsIntent = intent;
this._annotationsIntent = renderingIntent;
}
return this._annotationsPromise;
}
@ -1332,7 +1346,7 @@ class PDFPageProxy {
/**
* Begins the process of rendering a page to the desired context.
*
* @param {RenderParameters} params Page render parameters.
* @param {RenderParameters} params - Page render parameters.
* @returns {RenderTask} An object that contains a promise that is
* resolved when the page finishes rendering.
*/
@ -1473,10 +1487,12 @@ class PDFPageProxy {
}
/**
* @param {GetOperatorListParameters} params - Page getOperatorList
* parameters.
* @returns {Promise<PDFOperatorList>} A promise resolved with an
* {@link PDFOperatorList} object that represents page's operator list.
* {@link PDFOperatorList} object that represents the page's operator list.
*/
getOperatorList() {
getOperatorList({ intent = "display" } = {}) {
function operatorListChanged() {
if (intentState.operatorList.lastChunk) {
intentState.opListReadCapability.resolve(intentState.operatorList);
@ -1485,7 +1501,9 @@ class PDFPageProxy {
}
}
const renderingIntent = "oplist";
const renderingIntent = `oplist-${
intent === "print" ? "print" : "display"
}`;
let intentState = this._intentStates.get(renderingIntent);
if (!intentState) {
intentState = Object.create(null);
@ -1600,7 +1618,7 @@ class PDFPageProxy {
force: true,
});
if (intent === "oplist") {
if (intent.startsWith("oplist-")) {
// Avoid errors below, since the renderTasks are just stubs.
continue;
}

View File

@ -2401,7 +2401,7 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.restore();
}
beginAnnotation(rect, transform, matrix) {
beginAnnotation(id, rect, transform, matrix) {
this.save();
resetCtxToDefault(this.ctx);
this.current = new CanvasExtraState();

View File

@ -1689,6 +1689,12 @@ describe("annotation", function () {
OPS.setFillRGBColor,
OPS.endAnnotation,
]);
expect(operatorList.argsArray[0]).toEqual([
"271R",
[0, 0, 32, 10],
[32, 0, 0, 10, 0, 0],
[1, 0, 0, 1, 0, 0],
]);
expect(operatorList.argsArray[1]).toEqual(
new Uint8ClampedArray([26, 51, 76])
);
@ -2324,6 +2330,12 @@ describe("annotation", function () {
OPS.showText,
OPS.endAnnotation,
]);
expect(operatorList.argsArray[0]).toEqual([
"124R",
[0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0],
]);
expect(operatorList.argsArray[3][0][0].unicode).toEqual("4");
});
@ -2375,6 +2387,12 @@ describe("annotation", function () {
OPS.setFillRGBColor,
OPS.endAnnotation,
]);
expect(operatorList.argsArray[0]).toEqual([
"124R",
[0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0],
]);
expect(operatorList.argsArray[1]).toEqual(
new Uint8ClampedArray([26, 51, 76])
);
@ -2393,6 +2411,12 @@ describe("annotation", function () {
OPS.setFillRGBColor,
OPS.endAnnotation,
]);
expect(operatorList.argsArray[0]).toEqual([
"124R",
[0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0],
]);
expect(operatorList.argsArray[1]).toEqual(
new Uint8ClampedArray([76, 51, 26])
);
@ -2449,6 +2473,12 @@ describe("annotation", function () {
OPS.setFillRGBColor,
OPS.endAnnotation,
]);
expect(operatorList.argsArray[0]).toEqual([
"1249R",
[0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0],
]);
expect(operatorList.argsArray[1]).toEqual(
new Uint8ClampedArray([26, 51, 76])
);
@ -2503,6 +2533,12 @@ describe("annotation", function () {
OPS.setFillRGBColor,
OPS.endAnnotation,
]);
expect(operatorList.argsArray[0]).toEqual([
"124R",
[0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0],
]);
expect(operatorList.argsArray[1]).toEqual(
new Uint8ClampedArray([26, 51, 76])
);
@ -2700,6 +2736,12 @@ describe("annotation", function () {
OPS.setFillRGBColor,
OPS.endAnnotation,
]);
expect(operatorList.argsArray[0]).toEqual([
"124R",
[0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0],
]);
expect(operatorList.argsArray[1]).toEqual(
new Uint8ClampedArray([26, 51, 76])
);
@ -2718,6 +2760,12 @@ describe("annotation", function () {
OPS.setFillRGBColor,
OPS.endAnnotation,
]);
expect(operatorList.argsArray[0]).toEqual([
"124R",
[0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0],
]);
expect(operatorList.argsArray[1]).toEqual(
new Uint8ClampedArray([76, 51, 26])
);
@ -2772,6 +2820,12 @@ describe("annotation", function () {
OPS.setFillRGBColor,
OPS.endAnnotation,
]);
expect(operatorList.argsArray[0]).toEqual([
"124R",
[0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 1, 0, 0],
]);
expect(operatorList.argsArray[1]).toEqual(
new Uint8ClampedArray([76, 51, 26])
);

View File

@ -1622,8 +1622,9 @@ describe("api", function () {
it("gets operator list", async function () {
const operatorList = await page.getOperatorList();
expect(!!operatorList.fnArray).toEqual(true);
expect(!!operatorList.argsArray).toEqual(true);
expect(operatorList.fnArray.length).toBeGreaterThan(100);
expect(operatorList.argsArray.length).toBeGreaterThan(100);
expect(operatorList.lastChunk).toEqual(true);
});
@ -1687,6 +1688,26 @@ describe("api", function () {
}
);
it("gets operator list, containing Annotation-operatorLists", async function () {
const loadingTask = getDocument(
buildGetDocumentParams("annotation-line.pdf")
);
const pdfDoc = await loadingTask.promise;
const pdfPage = await pdfDoc.getPage(1);
const operatorList = await pdfPage.getOperatorList();
expect(operatorList.fnArray.length).toBeGreaterThan(20);
expect(operatorList.argsArray.length).toBeGreaterThan(20);
expect(operatorList.lastChunk).toEqual(true);
// The `getOperatorList` method, similar to the `render` method,
// is supposed to include any existing Annotation-operatorLists.
expect(operatorList.fnArray.includes(OPS.beginAnnotation)).toEqual(true);
expect(operatorList.fnArray.includes(OPS.endAnnotation)).toEqual(true);
await loadingTask.destroy();
});
it("gets document stats after parsing page", async function () {
const stats = await page.getOperatorList().then(function () {
return pdfDocument.getStats();