1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-20 15:18:08 +02:00

[api-minor] Implement basic support for OptionalContent Usage dicts (issue 5764, bug 1826783)

The following are some highlights of this patch:
 - In the Worker we only extract a *subset* of the potential contents of the `Usage` dictionary, to avoid having to implement/test a bunch of code that'd be completely unused in the viewer.

 - In order to still allow the user to *manually* override the default visible layers in the viewer, the viewable/printable state is purposely *not* enforced during initialization in the `OptionalContentConfig` constructor.

 - Printing will now always use the *default* visible layers, rather than using the same state as the viewer (as was the case previously).
   This ensures that the printing-output will correctly take the `Usage` dictionary into account, and in practice toggling of visible layers rarely seem to be necessary except in the viewer itself (if at all).[1]

---
[1] In the unlikely case that it'd ever be deemed necessary to support fine-grained control of optional content visibility during printing, some new (additional) UI would likely be needed to support that case.
This commit is contained in:
Jonas Jenwald 2024-02-25 14:12:36 +01:00
parent e647311a89
commit 3c78ff5fb0
13 changed files with 186 additions and 62 deletions

View file

@ -1796,7 +1796,6 @@ const PDFViewerApplication = {
pagesOverview: this.pdfViewer.getPagesOverview(),
printContainer: this.appConfig.printContainer,
printResolution: AppOptions.get("printResolution"),
optionalContentConfigPromise: this.pdfViewer.optionalContentConfigPromise,
printAnnotationStoragePromise: this._printAnnotationStoragePromise,
});
this.forceRendering();

View file

@ -119,15 +119,15 @@ class FirefoxPrintService {
pagesOverview,
printContainer,
printResolution,
optionalContentConfigPromise = null,
printAnnotationStoragePromise = null,
}) {
this.pdfDocument = pdfDocument;
this.pagesOverview = pagesOverview;
this.printContainer = printContainer;
this._printResolution = printResolution || 150;
this._optionalContentConfigPromise =
optionalContentConfigPromise || pdfDocument.getOptionalContentConfig();
this._optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
intent: "print",
});
this._printAnnotationStoragePromise =
printAnnotationStoragePromise || Promise.resolve();
}

View file

@ -258,14 +258,8 @@ if (PDFJSDev.test("GECKOVIEW")) {
const hasWillPrint =
pdfViewer.enableScripting &&
!!(await pdfDocument.getJSActions())?.WillPrint;
const hasUnchangedOptionalContent = (
await pdfViewer.optionalContentConfigPromise
).hasInitialVisibility;
result =
hasUnchangedAnnotations &&
!hasWillPrint &&
hasUnchangedOptionalContent;
result = hasUnchangedAnnotations && !hasWillPrint;
} catch {
console.warn("Unable to check if the document can be downloaded.");
}

View file

@ -182,7 +182,7 @@ class PDFLayerViewer extends BaseTreeViewer {
}
const pdfDocument = this._pdfDocument;
const optionalContentConfig = await (promise ||
pdfDocument.getOptionalContentConfig());
pdfDocument.getOptionalContentConfig({ intent: "display" }));
if (pdfDocument !== this._pdfDocument) {
return; // The document was closed while the optional content resolved.

View file

@ -13,7 +13,12 @@
* 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";
let activeService = null;
@ -58,7 +63,14 @@ function renderPage(
optionalContentConfigPromise,
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,
printContainer,
printResolution,
optionalContentConfigPromise = null,
printAnnotationStoragePromise = null,
}) {
this.pdfDocument = pdfDocument;
this.pagesOverview = pagesOverview;
this.printContainer = printContainer;
this._printResolution = printResolution || 150;
this._optionalContentConfigPromise =
optionalContentConfigPromise || pdfDocument.getOptionalContentConfig();
this._optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
intent: "print",
});
this._printAnnotationStoragePromise =
printAnnotationStoragePromise || Promise.resolve();
this.currentPage = -1;

View file

@ -189,7 +189,9 @@ class PDFThumbnailViewer {
return;
}
const firstPagePromise = pdfDocument.getPage(1);
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig();
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
intent: "display",
});
firstPagePromise
.then(firstPdfPage => {

View file

@ -781,7 +781,9 @@ class PDFViewer {
const pagesCount = pdfDocument.numPages;
const firstPagePromise = pdfDocument.getPage(1);
// Rendering (potentially) depends on this, hence fetching it immediately.
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig();
const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({
intent: "display",
});
const permissionsPromise = this.#enablePermissions
? pdfDocument.getPermissions()
: Promise.resolve();
@ -1822,7 +1824,7 @@ class PDFViewer {
console.error("optionalContentConfigPromise: Not initialized yet.");
// Prevent issues if the getter is accessed *before* the `onePageRendered`
// promise has resolved; won't (normally) happen in the default viewer.
return this.pdfDocument.getOptionalContentConfig();
return this.pdfDocument.getOptionalContentConfig({ intent: "display" });
}
return this._optionalContentConfigPromise;
}