Merge pull request #17726 from Snuffleupagus/OptionalContent-Usage
[api-minor] Implement basic support for OptionalContent `Usage` dicts (issue 5764, bug 1826783)
This commit is contained in:
commit
eb160726ee
@ -445,20 +445,10 @@ class Catalog {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
groupRefs.put(groupRef);
|
groupRefs.put(groupRef);
|
||||||
const group = this.xref.fetch(groupRef);
|
|
||||||
groups.push({
|
groups.push(this.#readOptionalContentGroup(groupRef));
|
||||||
id: groupRef.toString(),
|
|
||||||
name:
|
|
||||||
typeof group.get("Name") === "string"
|
|
||||||
? stringToPDFString(group.get("Name"))
|
|
||||||
: null,
|
|
||||||
intent:
|
|
||||||
typeof group.get("Intent") === "string"
|
|
||||||
? stringToPDFString(group.get("Intent"))
|
|
||||||
: null,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
config = this._readOptionalContentConfig(defaultConfig, groupRefs);
|
config = this.#readOptionalContentConfig(defaultConfig, groupRefs);
|
||||||
config.groups = groups;
|
config.groups = groups;
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
if (ex instanceof MissingDataException) {
|
if (ex instanceof MissingDataException) {
|
||||||
@ -469,7 +459,65 @@ class Catalog {
|
|||||||
return shadow(this, "optionalContentConfig", config);
|
return shadow(this, "optionalContentConfig", config);
|
||||||
}
|
}
|
||||||
|
|
||||||
_readOptionalContentConfig(config, contentGroupRefs) {
|
#readOptionalContentGroup(groupRef) {
|
||||||
|
const group = this.xref.fetch(groupRef);
|
||||||
|
const obj = {
|
||||||
|
id: groupRef.toString(),
|
||||||
|
name: null,
|
||||||
|
intent: null,
|
||||||
|
usage: {
|
||||||
|
print: null,
|
||||||
|
view: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const name = group.get("Name");
|
||||||
|
if (typeof name === "string") {
|
||||||
|
obj.name = stringToPDFString(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
let intent = group.getArray("Intent");
|
||||||
|
if (!Array.isArray(intent)) {
|
||||||
|
intent = [intent];
|
||||||
|
}
|
||||||
|
if (intent.every(i => i instanceof Name)) {
|
||||||
|
obj.intent = intent.map(i => i.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const usage = group.get("Usage");
|
||||||
|
if (!(usage instanceof Dict)) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
const usageObj = obj.usage;
|
||||||
|
|
||||||
|
const print = usage.get("Print");
|
||||||
|
if (print instanceof Dict) {
|
||||||
|
const printState = print.get("PrintState");
|
||||||
|
if (printState instanceof Name) {
|
||||||
|
switch (printState.name) {
|
||||||
|
case "ON":
|
||||||
|
case "OFF":
|
||||||
|
usageObj.print = { printState: printState.name };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const view = usage.get("View");
|
||||||
|
if (view instanceof Dict) {
|
||||||
|
const viewState = view.get("ViewState");
|
||||||
|
if (viewState instanceof Name) {
|
||||||
|
switch (viewState.name) {
|
||||||
|
case "ON":
|
||||||
|
case "OFF":
|
||||||
|
usageObj.view = { viewState: viewState.name };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
#readOptionalContentConfig(config, contentGroupRefs) {
|
||||||
function parseOnOff(refs) {
|
function parseOnOff(refs) {
|
||||||
const onParsed = [];
|
const onParsed = [];
|
||||||
if (Array.isArray(refs)) {
|
if (Array.isArray(refs)) {
|
||||||
|
@ -949,12 +949,26 @@ class PDFDocumentProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @typedef {Object} GetOptionalContentConfigParameters
|
||||||
|
* @property {string} [intent] - Determines the optional content groups that
|
||||||
|
* are visible by default; valid values are:
|
||||||
|
* - 'display' (viewable groups).
|
||||||
|
* - 'print' (printable groups).
|
||||||
|
* - 'any' (all groups).
|
||||||
|
* The default value is 'display'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {GetOptionalContentConfigParameters} [params] - Optional content
|
||||||
|
* config parameters.
|
||||||
* @returns {Promise<OptionalContentConfig>} A promise that is resolved with
|
* @returns {Promise<OptionalContentConfig>} A promise that is resolved with
|
||||||
* an {@link OptionalContentConfig} that contains all the optional content
|
* an {@link OptionalContentConfig} that contains all the optional content
|
||||||
* groups (assuming that the document has any).
|
* groups (assuming that the document has any).
|
||||||
*/
|
*/
|
||||||
getOptionalContentConfig() {
|
getOptionalContentConfig({ intent = "display" } = {}) {
|
||||||
return this._transport.getOptionalContentConfig();
|
const { renderingIntent } = this._transport.getRenderingIntent(intent);
|
||||||
|
|
||||||
|
return this._transport.getOptionalContentConfig(renderingIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1340,17 +1354,14 @@ class PDFPageProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {GetAnnotationsParameters} params - Annotation parameters.
|
* @param {GetAnnotationsParameters} [params] - Annotation parameters.
|
||||||
* @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 = "display" } = {}) {
|
getAnnotations({ intent = "display" } = {}) {
|
||||||
const intentArgs = this._transport.getRenderingIntent(intent);
|
const { renderingIntent } = this._transport.getRenderingIntent(intent);
|
||||||
|
|
||||||
return this._transport.getAnnotations(
|
return this._transport.getAnnotations(this._pageIndex, renderingIntent);
|
||||||
this._pageIndex,
|
|
||||||
intentArgs.renderingIntent
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1411,20 +1422,20 @@ class PDFPageProxy {
|
|||||||
annotationMode,
|
annotationMode,
|
||||||
printAnnotationStorage
|
printAnnotationStorage
|
||||||
);
|
);
|
||||||
|
const { renderingIntent, cacheKey } = intentArgs;
|
||||||
// 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;
|
||||||
// ... and ensure that a delayed cleanup is always aborted.
|
// ... and ensure that a delayed cleanup is always aborted.
|
||||||
this.#abortDelayedCleanup();
|
this.#abortDelayedCleanup();
|
||||||
|
|
||||||
if (!optionalContentConfigPromise) {
|
optionalContentConfigPromise ||=
|
||||||
optionalContentConfigPromise = this._transport.getOptionalContentConfig();
|
this._transport.getOptionalContentConfig(renderingIntent);
|
||||||
}
|
|
||||||
|
|
||||||
let intentState = this._intentStates.get(intentArgs.cacheKey);
|
let intentState = this._intentStates.get(cacheKey);
|
||||||
if (!intentState) {
|
if (!intentState) {
|
||||||
intentState = Object.create(null);
|
intentState = Object.create(null);
|
||||||
this._intentStates.set(intentArgs.cacheKey, intentState);
|
this._intentStates.set(cacheKey, intentState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that a pending `streamReader` cancel timeout is always aborted.
|
// Ensure that a pending `streamReader` cancel timeout is always aborted.
|
||||||
@ -1433,9 +1444,7 @@ class PDFPageProxy {
|
|||||||
intentState.streamReaderCancelTimeout = null;
|
intentState.streamReaderCancelTimeout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const intentPrint = !!(
|
const intentPrint = !!(renderingIntent & RenderingIntentFlag.PRINT);
|
||||||
intentArgs.renderingIntent & RenderingIntentFlag.PRINT
|
|
||||||
);
|
|
||||||
|
|
||||||
// If there's no displayReadyCapability yet, then the operatorList
|
// If there's no displayReadyCapability yet, then the operatorList
|
||||||
// was never requested before. Make the request and create the promise.
|
// was never requested before. Make the request and create the promise.
|
||||||
@ -1512,6 +1521,12 @@ class PDFPageProxy {
|
|||||||
}
|
}
|
||||||
this._stats?.time("Rendering");
|
this._stats?.time("Rendering");
|
||||||
|
|
||||||
|
if (!(optionalContentConfig.renderingIntent & renderingIntent)) {
|
||||||
|
throw new Error(
|
||||||
|
"Must use the same `intent`-argument when calling the `PDFPageProxy.render` " +
|
||||||
|
"and `PDFDocumentProxy.getOptionalContentConfig` methods."
|
||||||
|
);
|
||||||
|
}
|
||||||
internalRenderTask.initializeGraphics({
|
internalRenderTask.initializeGraphics({
|
||||||
transparency,
|
transparency,
|
||||||
optionalContentConfig,
|
optionalContentConfig,
|
||||||
@ -2994,10 +3009,10 @@ class WorkerTransport {
|
|||||||
return this.messageHandler.sendWithPromise("GetOutline", null);
|
return this.messageHandler.sendWithPromise("GetOutline", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
getOptionalContentConfig() {
|
getOptionalContentConfig(renderingIntent) {
|
||||||
return this.messageHandler
|
return this.#cacheSimpleMethod("GetOptionalContentConfig").then(
|
||||||
.sendWithPromise("GetOptionalContentConfig", null)
|
data => new OptionalContentConfig(data, renderingIntent)
|
||||||
.then(results => new OptionalContentConfig(results));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPermissions() {
|
getPermissions() {
|
||||||
|
@ -13,33 +13,63 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { info, objectFromMap, unreachable, warn } from "../shared/util.js";
|
import {
|
||||||
|
info,
|
||||||
|
objectFromMap,
|
||||||
|
RenderingIntentFlag,
|
||||||
|
unreachable,
|
||||||
|
warn,
|
||||||
|
} from "../shared/util.js";
|
||||||
import { MurmurHash3_64 } from "../shared/murmurhash3.js";
|
import { MurmurHash3_64 } from "../shared/murmurhash3.js";
|
||||||
|
|
||||||
const INTERNAL = Symbol("INTERNAL");
|
const INTERNAL = Symbol("INTERNAL");
|
||||||
|
|
||||||
class OptionalContentGroup {
|
class OptionalContentGroup {
|
||||||
|
#isDisplay = false;
|
||||||
|
|
||||||
|
#isPrint = false;
|
||||||
|
|
||||||
|
#userSet = false;
|
||||||
|
|
||||||
#visible = true;
|
#visible = true;
|
||||||
|
|
||||||
constructor(name, intent) {
|
constructor(renderingIntent, { name, intent, usage }) {
|
||||||
|
this.#isDisplay = !!(renderingIntent & RenderingIntentFlag.DISPLAY);
|
||||||
|
this.#isPrint = !!(renderingIntent & RenderingIntentFlag.PRINT);
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.intent = intent;
|
this.intent = intent;
|
||||||
|
this.usage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
get visible() {
|
get visible() {
|
||||||
|
if (this.#userSet) {
|
||||||
return this.#visible;
|
return this.#visible;
|
||||||
}
|
}
|
||||||
|
if (!this.#visible) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const { print, view } = this.usage;
|
||||||
|
|
||||||
|
if (this.#isDisplay) {
|
||||||
|
return view?.viewState !== "OFF";
|
||||||
|
} else if (this.#isPrint) {
|
||||||
|
return print?.printState !== "OFF";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
_setVisible(internal, visible) {
|
_setVisible(internal, visible, userSet = false) {
|
||||||
if (internal !== INTERNAL) {
|
if (internal !== INTERNAL) {
|
||||||
unreachable("Internal method `_setVisible` called.");
|
unreachable("Internal method `_setVisible` called.");
|
||||||
}
|
}
|
||||||
|
this.#userSet = userSet;
|
||||||
this.#visible = visible;
|
this.#visible = visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,7 +83,9 @@ class OptionalContentConfig {
|
|||||||
|
|
||||||
#order = null;
|
#order = null;
|
||||||
|
|
||||||
constructor(data) {
|
constructor(data, renderingIntent = RenderingIntentFlag.DISPLAY) {
|
||||||
|
this.renderingIntent = renderingIntent;
|
||||||
|
|
||||||
this.name = null;
|
this.name = null;
|
||||||
this.creator = null;
|
this.creator = null;
|
||||||
|
|
||||||
@ -66,7 +98,7 @@ class OptionalContentConfig {
|
|||||||
for (const group of data.groups) {
|
for (const group of data.groups) {
|
||||||
this.#groups.set(
|
this.#groups.set(
|
||||||
group.id,
|
group.id,
|
||||||
new OptionalContentGroup(group.name, group.intent)
|
new OptionalContentGroup(renderingIntent, group)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,11 +230,44 @@ class OptionalContentConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setVisibility(id, visible = true) {
|
setVisibility(id, visible = true) {
|
||||||
if (!this.#groups.has(id)) {
|
const group = this.#groups.get(id);
|
||||||
|
if (!group) {
|
||||||
warn(`Optional content group not found: ${id}`);
|
warn(`Optional content group not found: ${id}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.#groups.get(id)._setVisible(INTERNAL, !!visible);
|
group._setVisible(INTERNAL, !!visible, /* userSet = */ true);
|
||||||
|
|
||||||
|
this.#cachedGetHash = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setOCGState({ state, preserveRB }) {
|
||||||
|
let operator;
|
||||||
|
|
||||||
|
for (const elem of state) {
|
||||||
|
switch (elem) {
|
||||||
|
case "ON":
|
||||||
|
case "OFF":
|
||||||
|
case "Toggle":
|
||||||
|
operator = elem;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const group = this.#groups.get(elem);
|
||||||
|
if (!group) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (operator) {
|
||||||
|
case "ON":
|
||||||
|
group._setVisible(INTERNAL, true);
|
||||||
|
break;
|
||||||
|
case "OFF":
|
||||||
|
group._setVisible(INTERNAL, false);
|
||||||
|
break;
|
||||||
|
case "Toggle":
|
||||||
|
group._setVisible(INTERNAL, !group.visible);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.#cachedGetHash = null;
|
this.#cachedGetHash = null;
|
||||||
}
|
}
|
||||||
|
@ -684,7 +684,9 @@ class Driver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
task.pdfDoc = doc;
|
task.pdfDoc = doc;
|
||||||
task.optionalContentConfigPromise = doc.getOptionalContentConfig();
|
task.optionalContentConfigPromise = doc.getOptionalContentConfig({
|
||||||
|
intent: task.print ? "print" : "display",
|
||||||
|
});
|
||||||
|
|
||||||
if (task.optionalContent) {
|
if (task.optionalContent) {
|
||||||
const entries = Object.entries(task.optionalContent),
|
const entries = Object.entries(task.optionalContent),
|
||||||
|
1
test/pdfs/bug1826783.pdf.link
Normal file
1
test/pdfs/bug1826783.pdf.link
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://bugzilla.mozilla.org/attachment.cgi?id=9327375
|
@ -4016,6 +4016,23 @@
|
|||||||
"lastPage": 5,
|
"lastPage": 5,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "bug1826783-display",
|
||||||
|
"file": "pdfs/bug1826783.pdf",
|
||||||
|
"md5": "93e706efee15dd7b32d32d66f15a3ea2",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": true,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bug1826783-print",
|
||||||
|
"file": "pdfs/bug1826783.pdf",
|
||||||
|
"md5": "93e706efee15dd7b32d32d66f15a3ea2",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": true,
|
||||||
|
"type": "eq",
|
||||||
|
"print": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "issue8586",
|
"id": "issue8586",
|
||||||
"file": "pdfs/issue8586.pdf",
|
"file": "pdfs/issue8586.pdf",
|
||||||
|
@ -1796,7 +1796,6 @@ const PDFViewerApplication = {
|
|||||||
pagesOverview: this.pdfViewer.getPagesOverview(),
|
pagesOverview: this.pdfViewer.getPagesOverview(),
|
||||||
printContainer: this.appConfig.printContainer,
|
printContainer: this.appConfig.printContainer,
|
||||||
printResolution: AppOptions.get("printResolution"),
|
printResolution: AppOptions.get("printResolution"),
|
||||||
optionalContentConfigPromise: this.pdfViewer.optionalContentConfigPromise,
|
|
||||||
printAnnotationStoragePromise: this._printAnnotationStoragePromise,
|
printAnnotationStoragePromise: this._printAnnotationStoragePromise,
|
||||||
});
|
});
|
||||||
this.forceRendering();
|
this.forceRendering();
|
||||||
|
@ -119,15 +119,15 @@ class FirefoxPrintService {
|
|||||||
pagesOverview,
|
pagesOverview,
|
||||||
printContainer,
|
printContainer,
|
||||||
printResolution,
|
printResolution,
|
||||||
optionalContentConfigPromise = null,
|
|
||||||
printAnnotationStoragePromise = null,
|
printAnnotationStoragePromise = null,
|
||||||
}) {
|
}) {
|
||||||
this.pdfDocument = pdfDocument;
|
this.pdfDocument = pdfDocument;
|
||||||
this.pagesOverview = pagesOverview;
|
this.pagesOverview = pagesOverview;
|
||||||
this.printContainer = printContainer;
|
this.printContainer = printContainer;
|
||||||
this._printResolution = printResolution || 150;
|
this._printResolution = printResolution || 150;
|
||||||
this._optionalContentConfigPromise =
|
this._optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
|
||||||
optionalContentConfigPromise || pdfDocument.getOptionalContentConfig();
|
intent: "print",
|
||||||
|
});
|
||||||
this._printAnnotationStoragePromise =
|
this._printAnnotationStoragePromise =
|
||||||
printAnnotationStoragePromise || Promise.resolve();
|
printAnnotationStoragePromise || Promise.resolve();
|
||||||
}
|
}
|
||||||
|
@ -258,14 +258,8 @@ if (PDFJSDev.test("GECKOVIEW")) {
|
|||||||
const hasWillPrint =
|
const hasWillPrint =
|
||||||
pdfViewer.enableScripting &&
|
pdfViewer.enableScripting &&
|
||||||
!!(await pdfDocument.getJSActions())?.WillPrint;
|
!!(await pdfDocument.getJSActions())?.WillPrint;
|
||||||
const hasUnchangedOptionalContent = (
|
|
||||||
await pdfViewer.optionalContentConfigPromise
|
|
||||||
).hasInitialVisibility;
|
|
||||||
|
|
||||||
result =
|
result = hasUnchangedAnnotations && !hasWillPrint;
|
||||||
hasUnchangedAnnotations &&
|
|
||||||
!hasWillPrint &&
|
|
||||||
hasUnchangedOptionalContent;
|
|
||||||
} catch {
|
} catch {
|
||||||
console.warn("Unable to check if the document can be downloaded.");
|
console.warn("Unable to check if the document can be downloaded.");
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ class PDFLayerViewer extends BaseTreeViewer {
|
|||||||
}
|
}
|
||||||
const pdfDocument = this._pdfDocument;
|
const pdfDocument = this._pdfDocument;
|
||||||
const optionalContentConfig = await (promise ||
|
const optionalContentConfig = await (promise ||
|
||||||
pdfDocument.getOptionalContentConfig());
|
pdfDocument.getOptionalContentConfig({ intent: "display" }));
|
||||||
|
|
||||||
if (pdfDocument !== this._pdfDocument) {
|
if (pdfDocument !== this._pdfDocument) {
|
||||||
return; // The document was closed while the optional content resolved.
|
return; // The document was closed while the optional content resolved.
|
||||||
|
@ -517,31 +517,7 @@ class PDFLinkService {
|
|||||||
if (pdfDocument !== this.pdfDocument) {
|
if (pdfDocument !== this.pdfDocument) {
|
||||||
return; // The document was closed while the optional content resolved.
|
return; // The document was closed while the optional content resolved.
|
||||||
}
|
}
|
||||||
let operator;
|
optionalContentConfig.setOCGState(action);
|
||||||
|
|
||||||
for (const elem of action.state) {
|
|
||||||
switch (elem) {
|
|
||||||
case "ON":
|
|
||||||
case "OFF":
|
|
||||||
case "Toggle":
|
|
||||||
operator = elem;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (operator) {
|
|
||||||
case "ON":
|
|
||||||
optionalContentConfig.setVisibility(elem, true);
|
|
||||||
break;
|
|
||||||
case "OFF":
|
|
||||||
optionalContentConfig.setVisibility(elem, false);
|
|
||||||
break;
|
|
||||||
case "Toggle":
|
|
||||||
const group = optionalContentConfig.getGroup(elem);
|
|
||||||
if (group) {
|
|
||||||
optionalContentConfig.setVisibility(elem, !group.visible);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.pdfViewer.optionalContentConfigPromise = Promise.resolve(
|
this.pdfViewer.optionalContentConfigPromise = Promise.resolve(
|
||||||
optionalContentConfig
|
optionalContentConfig
|
||||||
|
@ -13,7 +13,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AnnotationMode, PixelsPerInch, shadow } from "pdfjs-lib";
|
import {
|
||||||
|
AnnotationMode,
|
||||||
|
PixelsPerInch,
|
||||||
|
RenderingCancelledException,
|
||||||
|
shadow,
|
||||||
|
} from "pdfjs-lib";
|
||||||
import { getXfaHtmlForPrinting } from "./print_utils.js";
|
import { getXfaHtmlForPrinting } from "./print_utils.js";
|
||||||
|
|
||||||
let activeService = null;
|
let activeService = null;
|
||||||
@ -58,7 +63,14 @@ function renderPage(
|
|||||||
optionalContentConfigPromise,
|
optionalContentConfigPromise,
|
||||||
printAnnotationStorage,
|
printAnnotationStorage,
|
||||||
};
|
};
|
||||||
return pdfPage.render(renderContext).promise;
|
const renderTask = pdfPage.render(renderContext);
|
||||||
|
|
||||||
|
return renderTask.promise.catch(reason => {
|
||||||
|
if (!(reason instanceof RenderingCancelledException)) {
|
||||||
|
console.error(reason);
|
||||||
|
}
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,15 +80,15 @@ class PDFPrintService {
|
|||||||
pagesOverview,
|
pagesOverview,
|
||||||
printContainer,
|
printContainer,
|
||||||
printResolution,
|
printResolution,
|
||||||
optionalContentConfigPromise = null,
|
|
||||||
printAnnotationStoragePromise = null,
|
printAnnotationStoragePromise = null,
|
||||||
}) {
|
}) {
|
||||||
this.pdfDocument = pdfDocument;
|
this.pdfDocument = pdfDocument;
|
||||||
this.pagesOverview = pagesOverview;
|
this.pagesOverview = pagesOverview;
|
||||||
this.printContainer = printContainer;
|
this.printContainer = printContainer;
|
||||||
this._printResolution = printResolution || 150;
|
this._printResolution = printResolution || 150;
|
||||||
this._optionalContentConfigPromise =
|
this._optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
|
||||||
optionalContentConfigPromise || pdfDocument.getOptionalContentConfig();
|
intent: "print",
|
||||||
|
});
|
||||||
this._printAnnotationStoragePromise =
|
this._printAnnotationStoragePromise =
|
||||||
printAnnotationStoragePromise || Promise.resolve();
|
printAnnotationStoragePromise || Promise.resolve();
|
||||||
this.currentPage = -1;
|
this.currentPage = -1;
|
||||||
|
@ -189,7 +189,9 @@ class PDFThumbnailViewer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const firstPagePromise = pdfDocument.getPage(1);
|
const firstPagePromise = pdfDocument.getPage(1);
|
||||||
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig();
|
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
|
||||||
|
intent: "display",
|
||||||
|
});
|
||||||
|
|
||||||
firstPagePromise
|
firstPagePromise
|
||||||
.then(firstPdfPage => {
|
.then(firstPdfPage => {
|
||||||
|
@ -781,7 +781,9 @@ class PDFViewer {
|
|||||||
const pagesCount = pdfDocument.numPages;
|
const pagesCount = pdfDocument.numPages;
|
||||||
const firstPagePromise = pdfDocument.getPage(1);
|
const firstPagePromise = pdfDocument.getPage(1);
|
||||||
// Rendering (potentially) depends on this, hence fetching it immediately.
|
// Rendering (potentially) depends on this, hence fetching it immediately.
|
||||||
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig();
|
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
|
||||||
|
intent: "display",
|
||||||
|
});
|
||||||
const permissionsPromise = this.#enablePermissions
|
const permissionsPromise = this.#enablePermissions
|
||||||
? pdfDocument.getPermissions()
|
? pdfDocument.getPermissions()
|
||||||
: Promise.resolve();
|
: Promise.resolve();
|
||||||
@ -1822,7 +1824,7 @@ class PDFViewer {
|
|||||||
console.error("optionalContentConfigPromise: Not initialized yet.");
|
console.error("optionalContentConfigPromise: Not initialized yet.");
|
||||||
// Prevent issues if the getter is accessed *before* the `onePageRendered`
|
// Prevent issues if the getter is accessed *before* the `onePageRendered`
|
||||||
// promise has resolved; won't (normally) happen in the default viewer.
|
// promise has resolved; won't (normally) happen in the default viewer.
|
||||||
return this.pdfDocument.getOptionalContentConfig();
|
return this.pdfDocument.getOptionalContentConfig({ intent: "display" });
|
||||||
}
|
}
|
||||||
return this._optionalContentConfigPromise;
|
return this._optionalContentConfigPromise;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user