|
14 | 14 | */
|
15 | 15 |
|
16 | 16 | import {
|
17 |
| - assert, bytesToString, createPromiseCapability, createValidAbsoluteUrl, |
18 |
| - FormatError, info, InvalidPDFException, isBool, isNum, isString, |
19 |
| - PermissionFlag, shadow, stringToPDFString, stringToUTF8String, unreachable, |
20 |
| - warn |
| 17 | + assert, bytesToString, createValidAbsoluteUrl, FormatError, info, |
| 18 | + InvalidPDFException, isBool, isNum, isString, PermissionFlag, shadow, |
| 19 | + stringToPDFString, stringToUTF8String, unreachable, warn |
21 | 20 | } from '../shared/util';
|
22 | 21 | import {
|
23 | 22 | clearPrimitiveCaches, Cmd, Dict, isCmd, isDict, isName, isRef, isRefsEqual,
|
@@ -680,99 +679,86 @@ class Catalog {
|
680 | 679 | });
|
681 | 680 | }
|
682 | 681 |
|
683 |
| - getPageDict(pageIndex) { |
684 |
| - const capability = createPromiseCapability(); |
| 682 | + async getPageDict(pageIndex) { |
685 | 683 | const nodesToVisit = [this.catDict.getRaw('Pages')];
|
686 | 684 | const xref = this.xref, pageKidsCountCache = this.pageKidsCountCache;
|
687 | 685 | let count, currentPageIndex = 0;
|
688 | 686 |
|
689 |
| - function next() { |
690 |
| - while (nodesToVisit.length) { |
691 |
| - const currentNode = nodesToVisit.pop(); |
| 687 | + while (nodesToVisit.length) { |
| 688 | + const currentNode = nodesToVisit.pop(); |
692 | 689 |
|
693 |
| - if (isRef(currentNode)) { |
694 |
| - count = pageKidsCountCache.get(currentNode); |
695 |
| - // Skip nodes where the page can't be. |
696 |
| - if (count > 0 && currentPageIndex + count < pageIndex) { |
697 |
| - currentPageIndex += count; |
698 |
| - continue; |
699 |
| - } |
| 690 | + if (currentNode instanceof Ref) { |
| 691 | + count = pageKidsCountCache.get(currentNode); |
| 692 | + // Skip nodes where the page can't be. |
| 693 | + if (count > 0 && currentPageIndex + count < pageIndex) { |
| 694 | + currentPageIndex += count; |
| 695 | + continue; |
| 696 | + } |
| 697 | + const obj = await xref.fetchAsync(currentNode); |
700 | 698 |
|
701 |
| - xref.fetchAsync(currentNode).then(function(obj) { |
702 |
| - if (isDict(obj, 'Page') || (isDict(obj) && !obj.has('Kids'))) { |
703 |
| - if (pageIndex === currentPageIndex) { |
704 |
| - // Cache the Page reference, since it can *greatly* improve |
705 |
| - // performance by reducing redundant lookups in long documents |
706 |
| - // where all nodes are found at *one* level of the tree. |
707 |
| - if (currentNode && !pageKidsCountCache.has(currentNode)) { |
708 |
| - pageKidsCountCache.put(currentNode, 1); |
709 |
| - } |
710 |
| - capability.resolve([obj, currentNode]); |
711 |
| - } else { |
712 |
| - currentPageIndex++; |
713 |
| - next(); |
714 |
| - } |
715 |
| - return; |
| 699 | + if ((obj instanceof Dict) && (isName(obj.get('Type'), 'Page') || |
| 700 | + (!obj.has('Type') && !obj.has('Kids')))) { |
| 701 | + if (pageIndex === currentPageIndex) { |
| 702 | + // Cache the Page reference, since it can *greatly* improve |
| 703 | + // performance by reducing redundant lookups in long documents |
| 704 | + // where all nodes are found at *one* level of the tree. |
| 705 | + if (currentNode && !pageKidsCountCache.has(currentNode)) { |
| 706 | + pageKidsCountCache.put(currentNode, 1); |
716 | 707 | }
|
717 |
| - nodesToVisit.push(obj); |
718 |
| - next(); |
719 |
| - }, capability.reject); |
720 |
| - return; |
| 708 | + return [obj, currentNode]; |
| 709 | + } |
| 710 | + currentPageIndex++; |
| 711 | + continue; |
721 | 712 | }
|
| 713 | + nodesToVisit.push(obj); |
| 714 | + continue; |
| 715 | + } |
722 | 716 |
|
723 |
| - // Must be a child page dictionary. |
724 |
| - if (!isDict(currentNode)) { |
725 |
| - capability.reject(new FormatError( |
726 |
| - 'Page dictionary kid reference points to wrong type of object.')); |
727 |
| - return; |
728 |
| - } |
| 717 | + // Must be a child page dictionary. |
| 718 | + if (!(currentNode instanceof Dict)) { |
| 719 | + throw new FormatError( |
| 720 | + 'Page dictionary kid reference points to wrong type of object.'); |
| 721 | + } |
729 | 722 |
|
730 |
| - count = currentNode.get('Count'); |
731 |
| - if (Number.isInteger(count) && count >= 0) { |
732 |
| - // Cache the Kids count, since it can reduce redundant lookups in |
733 |
| - // documents where all nodes are found at *one* level of the tree. |
734 |
| - const objId = currentNode.objId; |
735 |
| - if (objId && !pageKidsCountCache.has(objId)) { |
736 |
| - pageKidsCountCache.put(objId, count); |
737 |
| - } |
738 |
| - // Skip nodes where the page can't be. |
739 |
| - if (currentPageIndex + count <= pageIndex) { |
740 |
| - currentPageIndex += count; |
741 |
| - continue; |
742 |
| - } |
| 723 | + count = currentNode.get('Count'); |
| 724 | + if (Number.isInteger(count) && count >= 0) { |
| 725 | + // Cache the Kids count, since it can reduce redundant lookups in |
| 726 | + // documents where all nodes are found at *one* level of the tree. |
| 727 | + const objId = currentNode.objId; |
| 728 | + if (objId && !pageKidsCountCache.has(objId)) { |
| 729 | + pageKidsCountCache.put(objId, count); |
743 | 730 | }
|
| 731 | + // Skip nodes where the page can't be. |
| 732 | + if (currentPageIndex + count <= pageIndex) { |
| 733 | + currentPageIndex += count; |
| 734 | + continue; |
| 735 | + } |
| 736 | + } |
744 | 737 |
|
745 |
| - const kids = currentNode.get('Kids'); |
746 |
| - if (!Array.isArray(kids)) { |
747 |
| - // Prevent errors in corrupt PDF documents that violate the |
748 |
| - // specification by *inlining* Page dicts directly in the Kids |
749 |
| - // array, rather than using indirect objects (fixes issue9540.pdf). |
750 |
| - if (isName(currentNode.get('Type'), 'Page') || |
751 |
| - (!currentNode.has('Type') && currentNode.has('Contents'))) { |
752 |
| - if (currentPageIndex === pageIndex) { |
753 |
| - capability.resolve([currentNode, null]); |
754 |
| - return; |
755 |
| - } |
756 |
| - currentPageIndex++; |
757 |
| - continue; |
| 738 | + const kids = currentNode.get('Kids'); |
| 739 | + if (!Array.isArray(kids)) { |
| 740 | + // Prevent errors in corrupt PDF documents that violate the |
| 741 | + // specification by *inlining* Page dicts directly in the Kids |
| 742 | + // array, rather than using indirect objects (fixes issue9540.pdf). |
| 743 | + if (isName(currentNode.get('Type'), 'Page') || |
| 744 | + (!currentNode.has('Type') && currentNode.has('Contents'))) { |
| 745 | + if (currentPageIndex === pageIndex) { |
| 746 | + return [currentNode, null]; |
758 | 747 | }
|
759 |
| - |
760 |
| - capability.reject(new FormatError( |
761 |
| - 'Page dictionary kids object is not an array.')); |
762 |
| - return; |
| 748 | + currentPageIndex++; |
| 749 | + continue; |
763 | 750 | }
|
| 751 | + throw new FormatError('Page dictionary kids object is not an array.'); |
| 752 | + } |
764 | 753 |
|
765 |
| - // Always check all `Kids` nodes, to avoid getting stuck in an empty |
766 |
| - // node further down in the tree (see issue5644.pdf, issue8088.pdf), |
767 |
| - // and to ensure that we actually find the correct `Page` dict. |
768 |
| - for (let last = kids.length - 1; last >= 0; last--) { |
769 |
| - nodesToVisit.push(kids[last]); |
770 |
| - } |
| 754 | + // Always check all `Kids` nodes, to avoid getting stuck in an empty |
| 755 | + // node further down in the tree (see issue5644.pdf, issue8088.pdf), |
| 756 | + // and to ensure that we actually find the correct `Page` dict. |
| 757 | + for (let last = kids.length - 1; last >= 0; last--) { |
| 758 | + nodesToVisit.push(kids[last]); |
771 | 759 | }
|
772 |
| - capability.reject(new Error(`Page index ${pageIndex} not found.`)); |
773 | 760 | }
|
774 |
| - next(); |
775 |
| - return capability.promise; |
| 761 | + throw new Error(`Page index ${pageIndex} not found.`); |
776 | 762 | }
|
777 | 763 |
|
778 | 764 | getPageIndex(pageRef) {
|
|
0 commit comments