Merge pull request #13867 from Snuffleupagus/RenderingIntentFlag
[api-minor] Re-factor the *internal* renderingIntent, and change the default `intent` value in the `PDFPageProxy.getAnnotations` method
This commit is contained in:
commit
952f6366bf
@ -25,6 +25,7 @@ import {
|
|||||||
isString,
|
isString,
|
||||||
OPS,
|
OPS,
|
||||||
PageActionEventType,
|
PageActionEventType,
|
||||||
|
RenderingIntentFlag,
|
||||||
shadow,
|
shadow,
|
||||||
stringToBytes,
|
stringToBytes,
|
||||||
stringToPDFString,
|
stringToPDFString,
|
||||||
@ -319,14 +320,7 @@ class Page {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getOperatorList({
|
getOperatorList({ handler, sink, task, intent, annotationStorage }) {
|
||||||
handler,
|
|
||||||
sink,
|
|
||||||
task,
|
|
||||||
intent,
|
|
||||||
renderInteractiveForms,
|
|
||||||
annotationStorage,
|
|
||||||
}) {
|
|
||||||
const contentStreamPromise = this.getContentStream(handler);
|
const contentStreamPromise = this.getContentStream(handler);
|
||||||
const resourcesPromise = this.loadResources([
|
const resourcesPromise = this.loadResources([
|
||||||
"ColorSpace",
|
"ColorSpace",
|
||||||
@ -383,26 +377,26 @@ class Page {
|
|||||||
pageOpList.flush(true);
|
pageOpList.flush(true);
|
||||||
return { length: pageOpList.totalLength };
|
return { length: pageOpList.totalLength };
|
||||||
}
|
}
|
||||||
|
const renderForms = !!(intent & RenderingIntentFlag.ANNOTATION_FORMS),
|
||||||
|
intentAny = !!(intent & RenderingIntentFlag.ANY),
|
||||||
|
intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),
|
||||||
|
intentPrint = !!(intent & RenderingIntentFlag.PRINT);
|
||||||
|
|
||||||
// Collect the operator list promises for the annotations. Each promise
|
// Collect the operator list promises for the annotations. Each promise
|
||||||
// is resolved with the complete operator list for a single annotation.
|
// is resolved with the complete operator list for a single annotation.
|
||||||
const annotationIntent = intent.startsWith("oplist-")
|
|
||||||
? intent.split("-")[1]
|
|
||||||
: intent;
|
|
||||||
const opListPromises = [];
|
const opListPromises = [];
|
||||||
for (const annotation of annotations) {
|
for (const annotation of annotations) {
|
||||||
if (
|
if (
|
||||||
(annotationIntent === "display" &&
|
intentAny ||
|
||||||
annotation.mustBeViewed(annotationStorage)) ||
|
(intentDisplay && annotation.mustBeViewed(annotationStorage)) ||
|
||||||
(annotationIntent === "print" &&
|
(intentPrint && annotation.mustBePrinted(annotationStorage))
|
||||||
annotation.mustBePrinted(annotationStorage))
|
|
||||||
) {
|
) {
|
||||||
opListPromises.push(
|
opListPromises.push(
|
||||||
annotation
|
annotation
|
||||||
.getOperatorList(
|
.getOperatorList(
|
||||||
partialEvaluator,
|
partialEvaluator,
|
||||||
task,
|
task,
|
||||||
renderInteractiveForms,
|
renderForms,
|
||||||
annotationStorage
|
annotationStorage
|
||||||
)
|
)
|
||||||
.catch(function (reason) {
|
.catch(function (reason) {
|
||||||
@ -496,15 +490,23 @@ class Page {
|
|||||||
getAnnotationsData(intent) {
|
getAnnotationsData(intent) {
|
||||||
return this._parsedAnnotations.then(function (annotations) {
|
return this._parsedAnnotations.then(function (annotations) {
|
||||||
const annotationsData = [];
|
const annotationsData = [];
|
||||||
for (let i = 0, ii = annotations.length; i < ii; i++) {
|
|
||||||
|
if (annotations.length === 0) {
|
||||||
|
return annotationsData;
|
||||||
|
}
|
||||||
|
const intentAny = !!(intent & RenderingIntentFlag.ANY),
|
||||||
|
intentDisplay = !!(intent & RenderingIntentFlag.DISPLAY),
|
||||||
|
intentPrint = !!(intent & RenderingIntentFlag.PRINT);
|
||||||
|
|
||||||
|
for (const annotation of annotations) {
|
||||||
// Get the annotation even if it's hidden because
|
// Get the annotation even if it's hidden because
|
||||||
// JS can change its display.
|
// JS can change its display.
|
||||||
if (
|
if (
|
||||||
!intent ||
|
intentAny ||
|
||||||
(intent === "display" && annotations[i].viewable) ||
|
(intentDisplay && annotation.viewable) ||
|
||||||
(intent === "print" && annotations[i].printable)
|
(intentPrint && annotation.printable)
|
||||||
) {
|
) {
|
||||||
annotationsData.push(annotations[i].data);
|
annotationsData.push(annotation.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return annotationsData;
|
return annotationsData;
|
||||||
|
@ -13,7 +13,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert, ImageKind, OPS, shadow, warn } from "../shared/util.js";
|
import {
|
||||||
|
assert,
|
||||||
|
ImageKind,
|
||||||
|
OPS,
|
||||||
|
RenderingIntentFlag,
|
||||||
|
shadow,
|
||||||
|
warn,
|
||||||
|
} from "../shared/util.js";
|
||||||
|
|
||||||
function addState(parentState, pattern, checkFn, iterateFn, processFn) {
|
function addState(parentState, pattern, checkFn, iterateFn, processFn) {
|
||||||
let state = parentState;
|
let state = parentState;
|
||||||
@ -597,11 +604,11 @@ class OperatorList {
|
|||||||
return shadow(this, "CHUNK_SIZE_ABOUT", this.CHUNK_SIZE - 5);
|
return shadow(this, "CHUNK_SIZE_ABOUT", this.CHUNK_SIZE - 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(intent, streamSink) {
|
constructor(intent = 0, streamSink) {
|
||||||
this._streamSink = streamSink;
|
this._streamSink = streamSink;
|
||||||
this.fnArray = [];
|
this.fnArray = [];
|
||||||
this.argsArray = [];
|
this.argsArray = [];
|
||||||
if (streamSink && !(intent && intent.startsWith("oplist-"))) {
|
if (streamSink && !(intent & RenderingIntentFlag.OPLIST)) {
|
||||||
this.optimizer = new QueueOptimizer(this);
|
this.optimizer = new QueueOptimizer(this);
|
||||||
} else {
|
} else {
|
||||||
this.optimizer = new NullOptimizer(this);
|
this.optimizer = new NullOptimizer(this);
|
||||||
|
@ -688,7 +688,6 @@ class WorkerMessageHandler {
|
|||||||
sink,
|
sink,
|
||||||
task,
|
task,
|
||||||
intent: data.intent,
|
intent: data.intent,
|
||||||
renderInteractiveForms: data.renderInteractiveForms,
|
|
||||||
annotationStorage: data.annotationStorage,
|
annotationStorage: data.annotationStorage,
|
||||||
})
|
})
|
||||||
.then(
|
.then(
|
||||||
|
@ -28,6 +28,7 @@ import {
|
|||||||
isSameOrigin,
|
isSameOrigin,
|
||||||
MissingPDFException,
|
MissingPDFException,
|
||||||
PasswordException,
|
PasswordException,
|
||||||
|
RenderingIntentFlag,
|
||||||
setVerbosityLevel,
|
setVerbosityLevel,
|
||||||
shadow,
|
shadow,
|
||||||
stringToBytes,
|
stringToBytes,
|
||||||
@ -514,6 +515,29 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRenderingIntent(intent, { renderForms = false, isOpList = false }) {
|
||||||
|
let renderingIntent = RenderingIntentFlag.DISPLAY; // Default value.
|
||||||
|
switch (intent) {
|
||||||
|
case "any":
|
||||||
|
renderingIntent = RenderingIntentFlag.ANY;
|
||||||
|
break;
|
||||||
|
case "display":
|
||||||
|
break;
|
||||||
|
case "print":
|
||||||
|
renderingIntent = RenderingIntentFlag.PRINT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warn(`getRenderingIntent - invalid intent: ${intent}`);
|
||||||
|
}
|
||||||
|
if (renderForms) {
|
||||||
|
renderingIntent += RenderingIntentFlag.ANNOTATION_FORMS;
|
||||||
|
}
|
||||||
|
if (isOpList) {
|
||||||
|
renderingIntent += RenderingIntentFlag.OPLIST;
|
||||||
|
}
|
||||||
|
return renderingIntent;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} OnProgressParameters
|
* @typedef {Object} OnProgressParameters
|
||||||
* @property {number} loaded - Currently loaded number of bytes.
|
* @property {number} loaded - Currently loaded number of bytes.
|
||||||
@ -1120,8 +1144,8 @@ class PDFDocumentProxy {
|
|||||||
*
|
*
|
||||||
* @typedef {Object} GetAnnotationsParameters
|
* @typedef {Object} GetAnnotationsParameters
|
||||||
* @property {string} [intent] - Determines the annotations that are fetched,
|
* @property {string} [intent] - Determines the annotations that are fetched,
|
||||||
* can be either 'display' (viewable annotations) or 'print' (printable
|
* can be 'display' (viewable annotations), 'print' (printable annotations),
|
||||||
* annotations). If the parameter is omitted, all annotations are fetched.
|
* or 'any' (all annotations). The default value is 'display'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1131,8 +1155,8 @@ class PDFDocumentProxy {
|
|||||||
* @property {Object} canvasContext - A 2D context of a DOM Canvas object.
|
* @property {Object} canvasContext - A 2D context of a DOM Canvas object.
|
||||||
* @property {PageViewport} viewport - Rendering viewport obtained by calling
|
* @property {PageViewport} viewport - Rendering viewport obtained by calling
|
||||||
* the `PDFPageProxy.getViewport` method.
|
* the `PDFPageProxy.getViewport` method.
|
||||||
* @property {string} [intent] - Rendering intent, can be 'display' or 'print'.
|
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
|
||||||
* The default value is 'display'.
|
* or 'any'. The default value is 'display'.
|
||||||
* @property {boolean} [renderInteractiveForms] - Whether or not interactive
|
* @property {boolean} [renderInteractiveForms] - Whether or not interactive
|
||||||
* form elements are rendered in the display layer. If so, we do not render
|
* form elements are rendered in the display layer. If so, we do not render
|
||||||
* them on the canvas as well. The default value is `false`.
|
* them on the canvas as well. The default value is `false`.
|
||||||
@ -1161,8 +1185,8 @@ class PDFDocumentProxy {
|
|||||||
* Page getOperatorList parameters.
|
* Page getOperatorList parameters.
|
||||||
*
|
*
|
||||||
* @typedef {Object} GetOperatorListParameters
|
* @typedef {Object} GetOperatorListParameters
|
||||||
* @property {string} [intent] - Rendering intent, can be 'display' or 'print'.
|
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
|
||||||
* The default value is 'display'.
|
* or 'any'. The default value is 'display'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1276,9 +1300,8 @@ class PDFPageProxy {
|
|||||||
* @returns {Promise<Array<any>>} A promise that is resolved with an
|
* @returns {Promise<Array<any>>} A promise that is resolved with an
|
||||||
* {Array} of the annotation objects.
|
* {Array} of the annotation objects.
|
||||||
*/
|
*/
|
||||||
getAnnotations({ intent = null } = {}) {
|
getAnnotations({ intent = "display" } = {}) {
|
||||||
const renderingIntent =
|
const renderingIntent = getRenderingIntent(intent, {});
|
||||||
intent === "display" || intent === "print" ? intent : null;
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!this._annotationsPromise ||
|
!this._annotationsPromise ||
|
||||||
@ -1336,7 +1359,9 @@ class PDFPageProxy {
|
|||||||
this._stats.time("Overall");
|
this._stats.time("Overall");
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderingIntent = intent === "print" ? "print" : "display";
|
const renderingIntent = getRenderingIntent(intent, {
|
||||||
|
renderForms: renderInteractiveForms === true,
|
||||||
|
});
|
||||||
// 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;
|
||||||
@ -1380,7 +1405,6 @@ class PDFPageProxy {
|
|||||||
this._pumpOperatorList({
|
this._pumpOperatorList({
|
||||||
pageIndex: this._pageIndex,
|
pageIndex: this._pageIndex,
|
||||||
intent: renderingIntent,
|
intent: renderingIntent,
|
||||||
renderInteractiveForms: renderInteractiveForms === true,
|
|
||||||
annotationStorage,
|
annotationStorage,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1390,7 +1414,10 @@ class PDFPageProxy {
|
|||||||
|
|
||||||
// Attempt to reduce memory usage during *printing*, by always running
|
// Attempt to reduce memory usage during *printing*, by always running
|
||||||
// cleanup once rendering has finished (regardless of cleanupAfterRender).
|
// cleanup once rendering has finished (regardless of cleanupAfterRender).
|
||||||
if (this.cleanupAfterRender || renderingIntent === "print") {
|
if (
|
||||||
|
this.cleanupAfterRender ||
|
||||||
|
renderingIntent & RenderingIntentFlag.PRINT
|
||||||
|
) {
|
||||||
this.pendingCleanup = true;
|
this.pendingCleanup = true;
|
||||||
}
|
}
|
||||||
this._tryCleanup();
|
this._tryCleanup();
|
||||||
@ -1426,7 +1453,7 @@ class PDFPageProxy {
|
|||||||
operatorList: intentState.operatorList,
|
operatorList: intentState.operatorList,
|
||||||
pageIndex: this._pageIndex,
|
pageIndex: this._pageIndex,
|
||||||
canvasFactory: canvasFactoryInstance,
|
canvasFactory: canvasFactoryInstance,
|
||||||
useRequestAnimationFrame: renderingIntent !== "print",
|
useRequestAnimationFrame: !(renderingIntent & RenderingIntentFlag.PRINT),
|
||||||
pdfBug: this._pdfBug,
|
pdfBug: this._pdfBug,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1471,9 +1498,7 @@ class PDFPageProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderingIntent = `oplist-${
|
const renderingIntent = getRenderingIntent(intent, { isOpList: true });
|
||||||
intent === "print" ? "print" : "display"
|
|
||||||
}`;
|
|
||||||
let intentState = this._intentStates.get(renderingIntent);
|
let intentState = this._intentStates.get(renderingIntent);
|
||||||
if (!intentState) {
|
if (!intentState) {
|
||||||
intentState = Object.create(null);
|
intentState = Object.create(null);
|
||||||
@ -1588,7 +1613,7 @@ class PDFPageProxy {
|
|||||||
force: true,
|
force: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (intent.startsWith("oplist-")) {
|
if (intent & RenderingIntentFlag.OPLIST) {
|
||||||
// Avoid errors below, since the renderTasks are just stubs.
|
// Avoid errors below, since the renderTasks are just stubs.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,14 @@ import "./compatibility.js";
|
|||||||
const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
|
const IDENTITY_MATRIX = [1, 0, 0, 1, 0, 0];
|
||||||
const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
||||||
|
|
||||||
|
const RenderingIntentFlag = {
|
||||||
|
ANY: 0x01,
|
||||||
|
DISPLAY: 0x02,
|
||||||
|
PRINT: 0x04,
|
||||||
|
ANNOTATION_FORMS: 0x20,
|
||||||
|
OPLIST: 0x100,
|
||||||
|
};
|
||||||
|
|
||||||
// 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,
|
||||||
@ -1033,6 +1041,7 @@ export {
|
|||||||
PasswordResponses,
|
PasswordResponses,
|
||||||
PermissionFlag,
|
PermissionFlag,
|
||||||
removeNullCharacters,
|
removeNullCharacters,
|
||||||
|
RenderingIntentFlag,
|
||||||
setVerbosityLevel,
|
setVerbosityLevel,
|
||||||
shadow,
|
shadow,
|
||||||
StreamType,
|
StreamType,
|
||||||
|
@ -1443,6 +1443,12 @@ describe("api", function () {
|
|||||||
expect(data.length).toEqual(4);
|
expect(data.length).toEqual(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const anyPromise = page
|
||||||
|
.getAnnotations({ intent: "any" })
|
||||||
|
.then(function (data) {
|
||||||
|
expect(data.length).toEqual(4);
|
||||||
|
});
|
||||||
|
|
||||||
const displayPromise = page
|
const displayPromise = page
|
||||||
.getAnnotations({ intent: "display" })
|
.getAnnotations({ intent: "display" })
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
@ -1455,7 +1461,12 @@ describe("api", function () {
|
|||||||
expect(data.length).toEqual(4);
|
expect(data.length).toEqual(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all([defaultPromise, displayPromise, printPromise]);
|
await Promise.all([
|
||||||
|
defaultPromise,
|
||||||
|
anyPromise,
|
||||||
|
displayPromise,
|
||||||
|
printPromise,
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("gets annotations containing relative URLs (bug 766086)", async function () {
|
it("gets annotations containing relative URLs (bug 766086)", async function () {
|
||||||
|
Loading…
Reference in New Issue
Block a user