From f5c821e9c3b4e06b85aad8f68bb63d68e4cb73a3 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Fri, 23 Oct 2020 16:30:36 -0700 Subject: [PATCH] [api-minor] Implement API to get MarkInfo from the catalog. --- src/core/obj.js | 41 +++++++++++++++++++++++++++++++++++++++++ src/core/worker.js | 4 ++++ src/display/api.js | 21 +++++++++++++++++++++ test/unit/api_spec.js | 18 ++++++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/src/core/obj.js b/src/core/obj.js index a581317d9..9e8b14432 100644 --- a/src/core/obj.js +++ b/src/core/obj.js @@ -152,6 +152,47 @@ class Catalog { return shadow(this, "metadata", metadata); } + get markInfo() { + let markInfo = null; + try { + markInfo = this._readMarkInfo(); + } catch (ex) { + if (ex instanceof MissingDataException) { + throw ex; + } + warn("Unable to read mark info."); + } + return shadow(this, "markInfo", markInfo); + } + + /** + * @private + */ + _readMarkInfo() { + const obj = this._catDict.get("MarkInfo"); + if (!isDict(obj)) { + return null; + } + + const markInfo = Object.assign(Object.create(null), { + Marked: false, + UserProperties: false, + Suspects: false, + }); + for (const key in markInfo) { + if (!obj.has(key)) { + continue; + } + const value = obj.get(key); + if (!isBool(value)) { + continue; + } + markInfo[key] = value; + } + + return markInfo; + } + get toplevelPagesDict() { const pagesObj = this._catDict.get("Pages"); if (!isDict(pagesObj)) { diff --git a/src/core/worker.js b/src/core/worker.js index eae578ad6..7dee0f195 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -499,6 +499,10 @@ class WorkerMessageHandler { ]); }); + handler.on("GetMarkInfo", function wphSetupGetMarkInfo(data) { + return pdfManager.ensureCatalog("markInfo"); + }); + handler.on("GetData", function wphSetupGetData(data) { pdfManager.requestLoadedStream(); return pdfManager.onLoadedStream().then(function (stream) { diff --git a/src/display/api.js b/src/display/api.js index c6e7befb8..c450fc223 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -805,6 +805,23 @@ class PDFDocumentProxy { return this._transport.getMetadata(); } + /** + * @typedef {Object} MarkInfo + * Properties correspond to Table 321 of the PDF 32000-1:2008 spec. + * @property {boolean} Marked + * @property {boolean} UserProperties + * @property {boolean} Suspects + */ + + /** + * @returns {Promise} A promise that is resolved with + * a {MarkInfo} object that contains the MarkInfo flags for the PDF + * document, or `null` when no MarkInfo values are present in the PDF file. + */ + getMarkInfo() { + return this._transport.getMarkInfo(); + } + /** * @returns {Promise} A promise that is resolved with a * {TypedArray} that has the raw data from the PDF. @@ -2646,6 +2663,10 @@ class WorkerTransport { }); } + getMarkInfo() { + return this.messageHandler.sendWithPromise("GetMarkInfo", null); + } + getStats() { return this.messageHandler.sendWithPromise("GetStats", null); } diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 75c14813c..8a8a84bf8 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -1192,6 +1192,24 @@ describe("api", function () { .catch(done.fail); }); + it("gets markInfo", function (done) { + const loadingTask = getDocument( + buildGetDocumentParams("annotation-line.pdf") + ); + + loadingTask.promise + .then(function (pdfDoc) { + return pdfDoc.getMarkInfo(); + }) + .then(function (info) { + expect(info.Marked).toEqual(true); + expect(info.UserProperties).toEqual(false); + expect(info.Suspects).toEqual(false); + done(); + }) + .catch(done.fail); + }); + it("gets data", function (done) { var promise = pdfDocument.getData(); promise