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,
|
||||
OPS,
|
||||
PageActionEventType,
|
||||
RenderingIntentFlag,
|
||||
shadow,
|
||||
stringToBytes,
|
||||
stringToPDFString,
|
||||
@ -319,14 +320,7 @@ class Page {
|
||||
});
|
||||
}
|
||||
|
||||
getOperatorList({
|
||||
handler,
|
||||
sink,
|
||||
task,
|
||||
intent,
|
||||
renderInteractiveForms,
|
||||
annotationStorage,
|
||||
}) {
|
||||
getOperatorList({ handler, sink, task, intent, annotationStorage }) {
|
||||
const contentStreamPromise = this.getContentStream(handler);
|
||||
const resourcesPromise = this.loadResources([
|
||||
"ColorSpace",
|
||||
@ -383,26 +377,26 @@ class Page {
|
||||
pageOpList.flush(true);
|
||||
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
|
||||
// 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 (
|
||||
(annotationIntent === "display" &&
|
||||
annotation.mustBeViewed(annotationStorage)) ||
|
||||
(annotationIntent === "print" &&
|
||||
annotation.mustBePrinted(annotationStorage))
|
||||
intentAny ||
|
||||
(intentDisplay && annotation.mustBeViewed(annotationStorage)) ||
|
||||
(intentPrint && annotation.mustBePrinted(annotationStorage))
|
||||
) {
|
||||
opListPromises.push(
|
||||
annotation
|
||||
.getOperatorList(
|
||||
partialEvaluator,
|
||||
task,
|
||||
renderInteractiveForms,
|
||||
renderForms,
|
||||
annotationStorage
|
||||
)
|
||||
.catch(function (reason) {
|
||||
@ -496,15 +490,23 @@ class Page {
|
||||
getAnnotationsData(intent) {
|
||||
return this._parsedAnnotations.then(function (annotations) {
|
||||
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
|
||||
// JS can change its display.
|
||||
if (
|
||||
!intent ||
|
||||
(intent === "display" && annotations[i].viewable) ||
|
||||
(intent === "print" && annotations[i].printable)
|
||||
intentAny ||
|
||||
(intentDisplay && annotation.viewable) ||
|
||||
(intentPrint && annotation.printable)
|
||||
) {
|
||||
annotationsData.push(annotations[i].data);
|
||||
annotationsData.push(annotation.data);
|
||||
}
|
||||
}
|
||||
return annotationsData;
|
||||
|
@ -13,7 +13,14 @@
|
||||
* 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) {
|
||||
let state = parentState;
|
||||
@ -597,11 +604,11 @@ class OperatorList {
|
||||
return shadow(this, "CHUNK_SIZE_ABOUT", this.CHUNK_SIZE - 5);
|
||||
}
|
||||
|
||||
constructor(intent, streamSink) {
|
||||
constructor(intent = 0, streamSink) {
|
||||
this._streamSink = streamSink;
|
||||
this.fnArray = [];
|
||||
this.argsArray = [];
|
||||
if (streamSink && !(intent && intent.startsWith("oplist-"))) {
|
||||
if (streamSink && !(intent & RenderingIntentFlag.OPLIST)) {
|
||||
this.optimizer = new QueueOptimizer(this);
|
||||
} else {
|
||||
this.optimizer = new NullOptimizer(this);
|
||||
|
@ -688,7 +688,6 @@ class WorkerMessageHandler {
|
||||
sink,
|
||||
task,
|
||||
intent: data.intent,
|
||||
renderInteractiveForms: data.renderInteractiveForms,
|
||||
annotationStorage: data.annotationStorage,
|
||||
})
|
||||
.then(
|
||||
|
@ -28,6 +28,7 @@ import {
|
||||
isSameOrigin,
|
||||
MissingPDFException,
|
||||
PasswordException,
|
||||
RenderingIntentFlag,
|
||||
setVerbosityLevel,
|
||||
shadow,
|
||||
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
|
||||
* @property {number} loaded - Currently loaded number of bytes.
|
||||
@ -1120,8 +1144,8 @@ class PDFDocumentProxy {
|
||||
*
|
||||
* @typedef {Object} GetAnnotationsParameters
|
||||
* @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.
|
||||
* can be 'display' (viewable annotations), 'print' (printable annotations),
|
||||
* 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 {PageViewport} viewport - Rendering viewport obtained by calling
|
||||
* the `PDFPageProxy.getViewport` method.
|
||||
* @property {string} [intent] - Rendering intent, can be 'display' or 'print'.
|
||||
* The default value is 'display'.
|
||||
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
|
||||
* or 'any'. The default value is 'display'.
|
||||
* @property {boolean} [renderInteractiveForms] - Whether or not interactive
|
||||
* 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`.
|
||||
@ -1161,8 +1185,8 @@ class PDFDocumentProxy {
|
||||
* Page getOperatorList parameters.
|
||||
*
|
||||
* @typedef {Object} GetOperatorListParameters
|
||||
* @property {string} [intent] - Rendering intent, can be 'display' or 'print'.
|
||||
* The default value is 'display'.
|
||||
* @property {string} [intent] - Rendering intent, can be 'display', 'print',
|
||||
* or 'any'. The default value is 'display'.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -1276,9 +1300,8 @@ class PDFPageProxy {
|
||||
* @returns {Promise<Array<any>>} A promise that is resolved with an
|
||||
* {Array} of the annotation objects.
|
||||
*/
|
||||
getAnnotations({ intent = null } = {}) {
|
||||
const renderingIntent =
|
||||
intent === "display" || intent === "print" ? intent : null;
|
||||
getAnnotations({ intent = "display" } = {}) {
|
||||
const renderingIntent = getRenderingIntent(intent, {});
|
||||
|
||||
if (
|
||||
!this._annotationsPromise ||
|
||||
@ -1336,7 +1359,9 @@ class PDFPageProxy {
|
||||
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
|
||||
// this call to render.
|
||||
this.pendingCleanup = false;
|
||||
@ -1380,7 +1405,6 @@ class PDFPageProxy {
|
||||
this._pumpOperatorList({
|
||||
pageIndex: this._pageIndex,
|
||||
intent: renderingIntent,
|
||||
renderInteractiveForms: renderInteractiveForms === true,
|
||||
annotationStorage,
|
||||
});
|
||||
}
|
||||
@ -1390,7 +1414,10 @@ class PDFPageProxy {
|
||||
|
||||
// Attempt to reduce memory usage during *printing*, by always running
|
||||
// cleanup once rendering has finished (regardless of cleanupAfterRender).
|
||||
if (this.cleanupAfterRender || renderingIntent === "print") {
|
||||
if (
|
||||
this.cleanupAfterRender ||
|
||||
renderingIntent & RenderingIntentFlag.PRINT
|
||||
) {
|
||||
this.pendingCleanup = true;
|
||||
}
|
||||
this._tryCleanup();
|
||||
@ -1426,7 +1453,7 @@ class PDFPageProxy {
|
||||
operatorList: intentState.operatorList,
|
||||
pageIndex: this._pageIndex,
|
||||
canvasFactory: canvasFactoryInstance,
|
||||
useRequestAnimationFrame: renderingIntent !== "print",
|
||||
useRequestAnimationFrame: !(renderingIntent & RenderingIntentFlag.PRINT),
|
||||
pdfBug: this._pdfBug,
|
||||
});
|
||||
|
||||
@ -1471,9 +1498,7 @@ class PDFPageProxy {
|
||||
}
|
||||
}
|
||||
|
||||
const renderingIntent = `oplist-${
|
||||
intent === "print" ? "print" : "display"
|
||||
}`;
|
||||
const renderingIntent = getRenderingIntent(intent, { isOpList: true });
|
||||
let intentState = this._intentStates.get(renderingIntent);
|
||||
if (!intentState) {
|
||||
intentState = Object.create(null);
|
||||
@ -1588,7 +1613,7 @@ class PDFPageProxy {
|
||||
force: true,
|
||||
});
|
||||
|
||||
if (intent.startsWith("oplist-")) {
|
||||
if (intent & RenderingIntentFlag.OPLIST) {
|
||||
// Avoid errors below, since the renderTasks are just stubs.
|
||||
continue;
|
||||
}
|
||||
|
@ -18,6 +18,14 @@ import "./compatibility.js";
|
||||
const IDENTITY_MATRIX = [1, 0, 0, 1, 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.
|
||||
const PermissionFlag = {
|
||||
PRINT: 0x04,
|
||||
@ -1033,6 +1041,7 @@ export {
|
||||
PasswordResponses,
|
||||
PermissionFlag,
|
||||
removeNullCharacters,
|
||||
RenderingIntentFlag,
|
||||
setVerbosityLevel,
|
||||
shadow,
|
||||
StreamType,
|
||||
|
@ -1443,6 +1443,12 @@ describe("api", function () {
|
||||
expect(data.length).toEqual(4);
|
||||
});
|
||||
|
||||
const anyPromise = page
|
||||
.getAnnotations({ intent: "any" })
|
||||
.then(function (data) {
|
||||
expect(data.length).toEqual(4);
|
||||
});
|
||||
|
||||
const displayPromise = page
|
||||
.getAnnotations({ intent: "display" })
|
||||
.then(function (data) {
|
||||
@ -1455,7 +1461,12 @@ describe("api", function () {
|
||||
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 () {
|
||||
|
Loading…
Reference in New Issue
Block a user