document.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * Javascript code in this page
  4. *
  5. * Copyright 2020 Mozilla Foundation
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @licend The above is the entire license notice for the
  20. * Javascript code in this page
  21. */
  22. "use strict";
  23. Object.defineProperty(exports, "__esModule", {
  24. value: true
  25. });
  26. exports.PDFDocument = exports.Page = void 0;
  27. var _util = require("../shared/util.js");
  28. var _obj = require("./obj.js");
  29. var _primitives = require("./primitives.js");
  30. var _core_utils = require("./core_utils.js");
  31. var _stream = require("./stream.js");
  32. var _annotation = require("./annotation.js");
  33. var _crypto = require("./crypto.js");
  34. var _parser = require("./parser.js");
  35. var _operator_list = require("./operator_list.js");
  36. var _evaluator = require("./evaluator.js");
  37. var _function = require("./function.js");
  38. const DEFAULT_USER_UNIT = 1.0;
  39. const LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];
  40. function isAnnotationRenderable(annotation, intent) {
  41. return intent === "display" && annotation.viewable || intent === "print" && annotation.printable;
  42. }
  43. class Page {
  44. constructor({
  45. pdfManager,
  46. xref,
  47. pageIndex,
  48. pageDict,
  49. ref,
  50. fontCache,
  51. builtInCMapCache,
  52. pdfFunctionFactory
  53. }) {
  54. this.pdfManager = pdfManager;
  55. this.pageIndex = pageIndex;
  56. this.pageDict = pageDict;
  57. this.xref = xref;
  58. this.ref = ref;
  59. this.fontCache = fontCache;
  60. this.builtInCMapCache = builtInCMapCache;
  61. this.pdfFunctionFactory = pdfFunctionFactory;
  62. this.evaluatorOptions = pdfManager.evaluatorOptions;
  63. this.resourcesPromise = null;
  64. const idCounters = {
  65. obj: 0
  66. };
  67. this.idFactory = {
  68. createObjId() {
  69. return `p${pageIndex}_${++idCounters.obj}`;
  70. },
  71. getDocId() {
  72. return `g_${pdfManager.docId}`;
  73. }
  74. };
  75. }
  76. _getInheritableProperty(key, getArray = false) {
  77. const value = (0, _core_utils.getInheritableProperty)({
  78. dict: this.pageDict,
  79. key,
  80. getArray,
  81. stopWhenFound: false
  82. });
  83. if (!Array.isArray(value)) {
  84. return value;
  85. }
  86. if (value.length === 1 || !(0, _primitives.isDict)(value[0])) {
  87. return value[0];
  88. }
  89. return _primitives.Dict.merge(this.xref, value);
  90. }
  91. get content() {
  92. return this.pageDict.get("Contents");
  93. }
  94. get resources() {
  95. return (0, _util.shadow)(this, "resources", this._getInheritableProperty("Resources") || _primitives.Dict.empty);
  96. }
  97. _getBoundingBox(name) {
  98. const box = this._getInheritableProperty(name, true);
  99. if (Array.isArray(box) && box.length === 4) {
  100. if (box[2] - box[0] !== 0 && box[3] - box[1] !== 0) {
  101. return box;
  102. }
  103. (0, _util.warn)(`Empty /${name} entry.`);
  104. }
  105. return null;
  106. }
  107. get mediaBox() {
  108. return (0, _util.shadow)(this, "mediaBox", this._getBoundingBox("MediaBox") || LETTER_SIZE_MEDIABOX);
  109. }
  110. get cropBox() {
  111. return (0, _util.shadow)(this, "cropBox", this._getBoundingBox("CropBox") || this.mediaBox);
  112. }
  113. get userUnit() {
  114. let obj = this.pageDict.get("UserUnit");
  115. if (!(0, _util.isNum)(obj) || obj <= 0) {
  116. obj = DEFAULT_USER_UNIT;
  117. }
  118. return (0, _util.shadow)(this, "userUnit", obj);
  119. }
  120. get view() {
  121. const {
  122. cropBox,
  123. mediaBox
  124. } = this;
  125. let view;
  126. if (cropBox === mediaBox || (0, _util.isArrayEqual)(cropBox, mediaBox)) {
  127. view = mediaBox;
  128. } else {
  129. const box = _util.Util.intersect(cropBox, mediaBox);
  130. if (box && box[2] - box[0] !== 0 && box[3] - box[1] !== 0) {
  131. view = box;
  132. } else {
  133. (0, _util.warn)("Empty /CropBox and /MediaBox intersection.");
  134. }
  135. }
  136. return (0, _util.shadow)(this, "view", view || mediaBox);
  137. }
  138. get rotate() {
  139. let rotate = this._getInheritableProperty("Rotate") || 0;
  140. if (rotate % 90 !== 0) {
  141. rotate = 0;
  142. } else if (rotate >= 360) {
  143. rotate = rotate % 360;
  144. } else if (rotate < 0) {
  145. rotate = (rotate % 360 + 360) % 360;
  146. }
  147. return (0, _util.shadow)(this, "rotate", rotate);
  148. }
  149. getContentStream() {
  150. const content = this.content;
  151. let stream;
  152. if (Array.isArray(content)) {
  153. const xref = this.xref;
  154. const streams = [];
  155. for (const stream of content) {
  156. streams.push(xref.fetchIfRef(stream));
  157. }
  158. stream = new _stream.StreamsSequenceStream(streams);
  159. } else if ((0, _primitives.isStream)(content)) {
  160. stream = content;
  161. } else {
  162. stream = new _stream.NullStream();
  163. }
  164. return stream;
  165. }
  166. loadResources(keys) {
  167. if (!this.resourcesPromise) {
  168. this.resourcesPromise = this.pdfManager.ensure(this, "resources");
  169. }
  170. return this.resourcesPromise.then(() => {
  171. const objectLoader = new _obj.ObjectLoader(this.resources, keys, this.xref);
  172. return objectLoader.load();
  173. });
  174. }
  175. getOperatorList({
  176. handler,
  177. sink,
  178. task,
  179. intent,
  180. renderInteractiveForms
  181. }) {
  182. const contentStreamPromise = this.pdfManager.ensure(this, "getContentStream");
  183. const resourcesPromise = this.loadResources(["ExtGState", "ColorSpace", "Pattern", "Shading", "XObject", "Font"]);
  184. const partialEvaluator = new _evaluator.PartialEvaluator({
  185. xref: this.xref,
  186. handler,
  187. pageIndex: this.pageIndex,
  188. idFactory: this.idFactory,
  189. fontCache: this.fontCache,
  190. builtInCMapCache: this.builtInCMapCache,
  191. options: this.evaluatorOptions,
  192. pdfFunctionFactory: this.pdfFunctionFactory
  193. });
  194. const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
  195. const pageListPromise = dataPromises.then(([contentStream]) => {
  196. const opList = new _operator_list.OperatorList(intent, sink, this.pageIndex);
  197. handler.send("StartRenderPage", {
  198. transparency: partialEvaluator.hasBlendModes(this.resources),
  199. pageIndex: this.pageIndex,
  200. intent
  201. });
  202. return partialEvaluator.getOperatorList({
  203. stream: contentStream,
  204. task,
  205. resources: this.resources,
  206. operatorList: opList
  207. }).then(function () {
  208. return opList;
  209. });
  210. });
  211. return Promise.all([pageListPromise, this._parsedAnnotations]).then(function ([pageOpList, annotations]) {
  212. if (annotations.length === 0) {
  213. pageOpList.flush(true);
  214. return {
  215. length: pageOpList.totalLength
  216. };
  217. }
  218. const opListPromises = [];
  219. for (const annotation of annotations) {
  220. if (isAnnotationRenderable(annotation, intent)) {
  221. opListPromises.push(annotation.getOperatorList(partialEvaluator, task, renderInteractiveForms));
  222. }
  223. }
  224. return Promise.all(opListPromises).then(function (opLists) {
  225. pageOpList.addOp(_util.OPS.beginAnnotations, []);
  226. for (const opList of opLists) {
  227. pageOpList.addOpList(opList);
  228. }
  229. pageOpList.addOp(_util.OPS.endAnnotations, []);
  230. pageOpList.flush(true);
  231. return {
  232. length: pageOpList.totalLength
  233. };
  234. });
  235. });
  236. }
  237. extractTextContent({
  238. handler,
  239. task,
  240. normalizeWhitespace,
  241. sink,
  242. combineTextItems
  243. }) {
  244. const contentStreamPromise = this.pdfManager.ensure(this, "getContentStream");
  245. const resourcesPromise = this.loadResources(["ExtGState", "XObject", "Font"]);
  246. const dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
  247. return dataPromises.then(([contentStream]) => {
  248. const partialEvaluator = new _evaluator.PartialEvaluator({
  249. xref: this.xref,
  250. handler,
  251. pageIndex: this.pageIndex,
  252. idFactory: this.idFactory,
  253. fontCache: this.fontCache,
  254. builtInCMapCache: this.builtInCMapCache,
  255. options: this.evaluatorOptions,
  256. pdfFunctionFactory: this.pdfFunctionFactory
  257. });
  258. return partialEvaluator.getTextContent({
  259. stream: contentStream,
  260. task,
  261. resources: this.resources,
  262. normalizeWhitespace,
  263. combineTextItems,
  264. sink
  265. });
  266. });
  267. }
  268. getAnnotationsData(intent) {
  269. return this._parsedAnnotations.then(function (annotations) {
  270. const annotationsData = [];
  271. for (let i = 0, ii = annotations.length; i < ii; i++) {
  272. if (!intent || isAnnotationRenderable(annotations[i], intent)) {
  273. annotationsData.push(annotations[i].data);
  274. }
  275. }
  276. return annotationsData;
  277. });
  278. }
  279. get annotations() {
  280. return (0, _util.shadow)(this, "annotations", this._getInheritableProperty("Annots") || []);
  281. }
  282. get _parsedAnnotations() {
  283. const parsedAnnotations = this.pdfManager.ensure(this, "annotations").then(() => {
  284. const annotationRefs = this.annotations;
  285. const annotationPromises = [];
  286. for (let i = 0, ii = annotationRefs.length; i < ii; i++) {
  287. annotationPromises.push(_annotation.AnnotationFactory.create(this.xref, annotationRefs[i], this.pdfManager, this.idFactory));
  288. }
  289. return Promise.all(annotationPromises).then(function (annotations) {
  290. return annotations.filter(function isDefined(annotation) {
  291. return !!annotation;
  292. });
  293. }, function (reason) {
  294. (0, _util.warn)(`_parsedAnnotations: "${reason}".`);
  295. return [];
  296. });
  297. });
  298. return (0, _util.shadow)(this, "_parsedAnnotations", parsedAnnotations);
  299. }
  300. }
  301. exports.Page = Page;
  302. const PDF_HEADER_SIGNATURE = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2d]);
  303. const STARTXREF_SIGNATURE = new Uint8Array([0x73, 0x74, 0x61, 0x72, 0x74, 0x78, 0x72, 0x65, 0x66]);
  304. const ENDOBJ_SIGNATURE = new Uint8Array([0x65, 0x6e, 0x64, 0x6f, 0x62, 0x6a]);
  305. const FINGERPRINT_FIRST_BYTES = 1024;
  306. const EMPTY_FINGERPRINT = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
  307. const PDF_HEADER_VERSION_REGEXP = /^[1-9]\.[0-9]$/;
  308. function find(stream, signature, limit = 1024, backwards = false) {
  309. const signatureLength = signature.length;
  310. const scanBytes = stream.peekBytes(limit);
  311. const scanLength = scanBytes.length - signatureLength;
  312. if (scanLength <= 0) {
  313. return false;
  314. }
  315. if (backwards) {
  316. const signatureEnd = signatureLength - 1;
  317. let pos = scanBytes.length - 1;
  318. while (pos >= signatureEnd) {
  319. let j = 0;
  320. while (j < signatureLength && scanBytes[pos - j] === signature[signatureEnd - j]) {
  321. j++;
  322. }
  323. if (j >= signatureLength) {
  324. stream.pos += pos - signatureEnd;
  325. return true;
  326. }
  327. pos--;
  328. }
  329. } else {
  330. let pos = 0;
  331. while (pos <= scanLength) {
  332. let j = 0;
  333. while (j < signatureLength && scanBytes[pos + j] === signature[j]) {
  334. j++;
  335. }
  336. if (j >= signatureLength) {
  337. stream.pos += pos;
  338. return true;
  339. }
  340. pos++;
  341. }
  342. }
  343. return false;
  344. }
  345. class PDFDocument {
  346. constructor(pdfManager, arg) {
  347. let stream;
  348. if ((0, _primitives.isStream)(arg)) {
  349. stream = arg;
  350. } else if ((0, _util.isArrayBuffer)(arg)) {
  351. stream = new _stream.Stream(arg);
  352. } else {
  353. throw new Error("PDFDocument: Unknown argument type");
  354. }
  355. if (stream.length <= 0) {
  356. throw new _util.InvalidPDFException("The PDF file is empty, i.e. its size is zero bytes.");
  357. }
  358. this.pdfManager = pdfManager;
  359. this.stream = stream;
  360. this.xref = new _obj.XRef(stream, pdfManager);
  361. this.pdfFunctionFactory = new _function.PDFFunctionFactory({
  362. xref: this.xref,
  363. isEvalSupported: pdfManager.evaluatorOptions.isEvalSupported
  364. });
  365. this._pagePromises = [];
  366. }
  367. parse(recoveryMode) {
  368. this.setup(recoveryMode);
  369. const version = this.catalog.catDict.get("Version");
  370. if ((0, _primitives.isName)(version)) {
  371. this.pdfFormatVersion = version.name;
  372. }
  373. try {
  374. this.acroForm = this.catalog.catDict.get("AcroForm");
  375. if (this.acroForm) {
  376. this.xfa = this.acroForm.get("XFA");
  377. const fields = this.acroForm.get("Fields");
  378. if ((!Array.isArray(fields) || fields.length === 0) && !this.xfa) {
  379. this.acroForm = null;
  380. }
  381. }
  382. } catch (ex) {
  383. if (ex instanceof _core_utils.MissingDataException) {
  384. throw ex;
  385. }
  386. (0, _util.info)("Cannot fetch AcroForm entry; assuming no AcroForms are present");
  387. this.acroForm = null;
  388. }
  389. try {
  390. const collection = this.catalog.catDict.get("Collection");
  391. if ((0, _primitives.isDict)(collection) && collection.getKeys().length > 0) {
  392. this.collection = collection;
  393. }
  394. } catch (ex) {
  395. if (ex instanceof _core_utils.MissingDataException) {
  396. throw ex;
  397. }
  398. (0, _util.info)("Cannot fetch Collection dictionary.");
  399. }
  400. }
  401. get linearization() {
  402. let linearization = null;
  403. try {
  404. linearization = _parser.Linearization.create(this.stream);
  405. } catch (err) {
  406. if (err instanceof _core_utils.MissingDataException) {
  407. throw err;
  408. }
  409. (0, _util.info)(err);
  410. }
  411. return (0, _util.shadow)(this, "linearization", linearization);
  412. }
  413. get startXRef() {
  414. const stream = this.stream;
  415. let startXRef = 0;
  416. if (this.linearization) {
  417. stream.reset();
  418. if (find(stream, ENDOBJ_SIGNATURE)) {
  419. startXRef = stream.pos + 6 - stream.start;
  420. }
  421. } else {
  422. const step = 1024;
  423. const startXRefLength = STARTXREF_SIGNATURE.length;
  424. let found = false,
  425. pos = stream.end;
  426. while (!found && pos > 0) {
  427. pos -= step - startXRefLength;
  428. if (pos < 0) {
  429. pos = 0;
  430. }
  431. stream.pos = pos;
  432. found = find(stream, STARTXREF_SIGNATURE, step, true);
  433. }
  434. if (found) {
  435. stream.skip(9);
  436. let ch;
  437. do {
  438. ch = stream.getByte();
  439. } while ((0, _core_utils.isWhiteSpace)(ch));
  440. let str = "";
  441. while (ch >= 0x20 && ch <= 0x39) {
  442. str += String.fromCharCode(ch);
  443. ch = stream.getByte();
  444. }
  445. startXRef = parseInt(str, 10);
  446. if (isNaN(startXRef)) {
  447. startXRef = 0;
  448. }
  449. }
  450. }
  451. return (0, _util.shadow)(this, "startXRef", startXRef);
  452. }
  453. checkHeader() {
  454. const stream = this.stream;
  455. stream.reset();
  456. if (!find(stream, PDF_HEADER_SIGNATURE)) {
  457. return;
  458. }
  459. stream.moveStart();
  460. const MAX_PDF_VERSION_LENGTH = 12;
  461. let version = "",
  462. ch;
  463. while ((ch = stream.getByte()) > 0x20) {
  464. if (version.length >= MAX_PDF_VERSION_LENGTH) {
  465. break;
  466. }
  467. version += String.fromCharCode(ch);
  468. }
  469. if (!this.pdfFormatVersion) {
  470. this.pdfFormatVersion = version.substring(5);
  471. }
  472. }
  473. parseStartXRef() {
  474. this.xref.setStartXRef(this.startXRef);
  475. }
  476. setup(recoveryMode) {
  477. this.xref.parse(recoveryMode);
  478. this.catalog = new _obj.Catalog(this.pdfManager, this.xref);
  479. }
  480. get numPages() {
  481. const linearization = this.linearization;
  482. const num = linearization ? linearization.numPages : this.catalog.numPages;
  483. return (0, _util.shadow)(this, "numPages", num);
  484. }
  485. get documentInfo() {
  486. const DocumentInfoValidators = {
  487. Title: _util.isString,
  488. Author: _util.isString,
  489. Subject: _util.isString,
  490. Keywords: _util.isString,
  491. Creator: _util.isString,
  492. Producer: _util.isString,
  493. CreationDate: _util.isString,
  494. ModDate: _util.isString,
  495. Trapped: _primitives.isName
  496. };
  497. let version = this.pdfFormatVersion;
  498. if (typeof version !== "string" || !PDF_HEADER_VERSION_REGEXP.test(version)) {
  499. (0, _util.warn)(`Invalid PDF header version number: ${version}`);
  500. version = null;
  501. }
  502. const docInfo = {
  503. PDFFormatVersion: version,
  504. IsLinearized: !!this.linearization,
  505. IsAcroFormPresent: !!this.acroForm,
  506. IsXFAPresent: !!this.xfa,
  507. IsCollectionPresent: !!this.collection
  508. };
  509. let infoDict;
  510. try {
  511. infoDict = this.xref.trailer.get("Info");
  512. } catch (err) {
  513. if (err instanceof _core_utils.MissingDataException) {
  514. throw err;
  515. }
  516. (0, _util.info)("The document information dictionary is invalid.");
  517. }
  518. if ((0, _primitives.isDict)(infoDict)) {
  519. for (const key of infoDict.getKeys()) {
  520. const value = infoDict.get(key);
  521. if (DocumentInfoValidators[key]) {
  522. if (DocumentInfoValidators[key](value)) {
  523. docInfo[key] = typeof value !== "string" ? value : (0, _util.stringToPDFString)(value);
  524. } else {
  525. (0, _util.info)(`Bad value in document info for "${key}".`);
  526. }
  527. } else if (typeof key === "string") {
  528. let customValue;
  529. if ((0, _util.isString)(value)) {
  530. customValue = (0, _util.stringToPDFString)(value);
  531. } else if ((0, _primitives.isName)(value) || (0, _util.isNum)(value) || (0, _util.isBool)(value)) {
  532. customValue = value;
  533. } else {
  534. (0, _util.info)(`Unsupported value in document info for (custom) "${key}".`);
  535. continue;
  536. }
  537. if (!docInfo["Custom"]) {
  538. docInfo["Custom"] = Object.create(null);
  539. }
  540. docInfo["Custom"][key] = customValue;
  541. }
  542. }
  543. }
  544. return (0, _util.shadow)(this, "documentInfo", docInfo);
  545. }
  546. get fingerprint() {
  547. let hash;
  548. const idArray = this.xref.trailer.get("ID");
  549. if (Array.isArray(idArray) && idArray[0] && (0, _util.isString)(idArray[0]) && idArray[0] !== EMPTY_FINGERPRINT) {
  550. hash = (0, _util.stringToBytes)(idArray[0]);
  551. } else {
  552. hash = (0, _crypto.calculateMD5)(this.stream.getByteRange(0, FINGERPRINT_FIRST_BYTES), 0, FINGERPRINT_FIRST_BYTES);
  553. }
  554. const fingerprintBuf = [];
  555. for (let i = 0, ii = hash.length; i < ii; i++) {
  556. const hex = hash[i].toString(16);
  557. fingerprintBuf.push(hex.padStart(2, "0"));
  558. }
  559. return (0, _util.shadow)(this, "fingerprint", fingerprintBuf.join(""));
  560. }
  561. _getLinearizationPage(pageIndex) {
  562. const {
  563. catalog,
  564. linearization
  565. } = this;
  566. (0, _util.assert)(linearization && linearization.pageFirst === pageIndex);
  567. const ref = _primitives.Ref.get(linearization.objectNumberFirst, 0);
  568. return this.xref.fetchAsync(ref).then(obj => {
  569. if ((0, _primitives.isDict)(obj, "Page") || (0, _primitives.isDict)(obj) && !obj.has("Type") && obj.has("Contents")) {
  570. if (ref && !catalog.pageKidsCountCache.has(ref)) {
  571. catalog.pageKidsCountCache.put(ref, 1);
  572. }
  573. return [obj, ref];
  574. }
  575. throw new _util.FormatError("The Linearization dictionary doesn't point " + "to a valid Page dictionary.");
  576. }).catch(reason => {
  577. (0, _util.info)(reason);
  578. return catalog.getPageDict(pageIndex);
  579. });
  580. }
  581. getPage(pageIndex) {
  582. if (this._pagePromises[pageIndex] !== undefined) {
  583. return this._pagePromises[pageIndex];
  584. }
  585. const {
  586. catalog,
  587. linearization
  588. } = this;
  589. const promise = linearization && linearization.pageFirst === pageIndex ? this._getLinearizationPage(pageIndex) : catalog.getPageDict(pageIndex);
  590. return this._pagePromises[pageIndex] = promise.then(([pageDict, ref]) => {
  591. return new Page({
  592. pdfManager: this.pdfManager,
  593. xref: this.xref,
  594. pageIndex,
  595. pageDict,
  596. ref,
  597. fontCache: catalog.fontCache,
  598. builtInCMapCache: catalog.builtInCMapCache,
  599. pdfFunctionFactory: this.pdfFunctionFactory
  600. });
  601. });
  602. }
  603. checkFirstPage() {
  604. return this.getPage(0).catch(async reason => {
  605. if (reason instanceof _core_utils.XRefEntryException) {
  606. this._pagePromises.length = 0;
  607. await this.cleanup();
  608. throw new _core_utils.XRefParseException();
  609. }
  610. });
  611. }
  612. fontFallback(id, handler) {
  613. return this.catalog.fontFallback(id, handler);
  614. }
  615. async cleanup() {
  616. return this.catalog ? this.catalog.cleanup() : (0, _primitives.clearPrimitiveCaches)();
  617. }
  618. }
  619. exports.PDFDocument = PDFDocument;