瀏覽代碼

PDF.js version 2.16.105 - See https://github.com/mozilla/pdf.js/releases/tag/v2.16.105

pdfjsbot 2 年之前
父節點
當前提交
cc3d3bf299
共有 100 個文件被更改,包括 5574 次插入5591 次删除
  1. 1 1
      README.md
  2. 1 1
      bower.json
  3. 2785 2696
      build/pdf.js
  4. 0 0
      build/pdf.js.map
  5. 0 0
      build/pdf.min.js
  6. 2 2
      build/pdf.sandbox.js
  7. 0 0
      build/pdf.sandbox.js.map
  8. 0 0
      build/pdf.sandbox.min.js
  9. 132 233
      build/pdf.worker.js
  10. 0 0
      build/pdf.worker.js.map
  11. 0 0
      build/pdf.worker.min.js
  12. 5 5
      image_decoders/pdf.image_decoders.js
  13. 0 0
      image_decoders/pdf.image_decoders.js.map
  14. 0 0
      image_decoders/pdf.image_decoders.min.js
  15. 286 433
      legacy/build/pdf.js
  16. 0 0
      legacy/build/pdf.js.map
  17. 0 0
      legacy/build/pdf.min.js
  18. 0 0
      legacy/build/pdf.sandbox.js
  19. 0 0
      legacy/build/pdf.sandbox.js.map
  20. 0 0
      legacy/build/pdf.sandbox.min.js
  21. 0 2
      legacy/build/pdf.worker.js
  22. 0 0
      legacy/build/pdf.worker.js.map
  23. 0 0
      legacy/build/pdf.worker.min.js
  24. 276 423
      legacy/image_decoders/pdf.image_decoders.js
  25. 0 0
      legacy/image_decoders/pdf.image_decoders.js.map
  26. 0 0
      legacy/image_decoders/pdf.image_decoders.min.js
  27. 19 3
      legacy/web/pdf_viewer.css
  28. 99 144
      legacy/web/pdf_viewer.js
  29. 0 0
      legacy/web/pdf_viewer.js.map
  30. 57 3
      lib/core/annotation.js
  31. 0 0
      lib/core/cff_parser.js
  32. 69 17
      lib/core/document.js
  33. 1 1
      lib/core/evaluator.js
  34. 307 311
      lib/core/function.js
  35. 3 3
      lib/core/jbig2.js
  36. 521 530
      lib/core/type1_parser.js
  37. 9 2
      lib/core/worker.js
  38. 102 40
      lib/display/annotation_layer.js
  39. 16 1
      lib/display/annotation_storage.js
  40. 9 7
      lib/display/api.js
  41. 76 246
      lib/display/canvas.js
  42. 26 25
      lib/display/display_utils.js
  43. 21 158
      lib/display/editor/annotation_editor_layer.js
  44. 0 4
      lib/display/editor/editor.js
  45. 10 8
      lib/display/editor/freetext.js
  46. 4 3
      lib/display/editor/ink.js
  47. 0 13
      lib/display/editor/tools.js
  48. 5 16
      lib/display/fetch_stream.js
  49. 10 8
      lib/display/pattern_helper.js
  50. 4 10
      lib/pdf.js
  51. 2 2
      lib/pdf.sandbox.js
  52. 2 2
      lib/pdf.worker.js
  53. 16 2
      lib/test/unit/annotation_spec.js
  54. 25 3
      lib/test/unit/api_spec.js
  55. 0 33
      lib/test/unit/display_utils_spec.js
  56. 2 2
      lib/test/unit/jasmine-boot.js
  57. 1 1
      lib/test/unit/scripting_spec.js
  58. 33 0
      lib/test/unit/ui_utils_spec.js
  59. 2 0
      lib/web/annotation_editor_layer_builder.js
  60. 5 2
      lib/web/annotation_layer_builder.js
  61. 71 4
      lib/web/app.js
  62. 0 6
      lib/web/app_options.js
  63. 33 13
      lib/web/base_viewer.js
  64. 10 4
      lib/web/default_factory.js
  65. 1 1
      lib/web/firefox_print_service.js
  66. 6 3
      lib/web/interfaces.js
  67. 21 3
      lib/web/password_prompt.js
  68. 4 4
      lib/web/pdf_find_controller.js
  69. 16 9
      lib/web/pdf_page_view.js
  70. 1 0
      lib/web/pdf_presentation_mode.js
  71. 6 1
      lib/web/pdf_thumbnail_view.js
  72. 20 2
      lib/web/pdf_viewer.component.js
  73. 1 1
      lib/web/secondary_toolbar.js
  74. 221 0
      lib/web/text_accessibility.js
  75. 6 1
      lib/web/text_layer_builder.js
  76. 28 40
      lib/web/toolbar.js
  77. 28 4
      lib/web/ui_utils.js
  78. 1 1
      package.json
  79. 3 2
      types/src/display/annotation_layer.d.ts
  80. 2 1
      types/src/display/annotation_storage.d.ts
  81. 19 9
      types/src/display/api.d.ts
  82. 1 2
      types/src/display/canvas.d.ts
  83. 3 10
      types/src/display/display_utils.d.ts
  84. 4 30
      types/src/display/editor/annotation_editor_layer.d.ts
  85. 0 5
      types/src/display/editor/editor.d.ts
  86. 1 0
      types/src/display/editor/freetext.d.ts
  87. 1 0
      types/src/display/editor/ink.d.ts
  88. 0 3
      types/src/display/editor/tools.d.ts
  89. 2 2
      types/src/display/fetch_stream.d.ts
  90. 1 2
      types/src/pdf.d.ts
  91. 4 0
      types/web/annotation_editor_layer_builder.d.ts
  92. 5 1
      types/web/annotation_layer_builder.d.ts
  93. 14 4
      types/web/base_viewer.d.ts
  94. 13 4
      types/web/default_factory.d.ts
  95. 14 4
      types/web/interfaces.d.ts
  96. 1 1
      types/web/pdf_link_service.d.ts
  97. 21 16
      types/web/pdf_page_view.d.ts
  98. 1 1
      types/web/pdf_thumbnail_view.d.ts
  99. 4 1
      types/web/pdf_viewer.component.d.ts
  100. 42 0
      types/web/text_accessibility.d.ts

+ 1 - 1
README.md

@@ -8,7 +8,7 @@ This is a pre-built version of the PDF.js source code. It is automatically
 generated by the build scripts.
 
 For usage with older browsers or environments, without support for modern
-features such as `async`/`await`, optional chaining, nullish coalescing,
+features such as optional chaining, nullish coalescing,
 and private `class` fields/methods; please see the `legacy/` folder.
 
 See https://github.com/mozilla/pdf.js for learning and contributing.

+ 1 - 1
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "pdfjs-dist",
-  "version": "2.15.349",
+  "version": "2.16.105",
   "main": [
     "build/pdf.js",
     "build/pdf.worker.js"

文件差異過大導致無法顯示
+ 2785 - 2696
build/pdf.js


文件差異過大導致無法顯示
+ 0 - 0
build/pdf.js.map


文件差異過大導致無法顯示
+ 0 - 0
build/pdf.min.js


文件差異過大導致無法顯示
+ 2 - 2
build/pdf.sandbox.js


文件差異過大導致無法顯示
+ 0 - 0
build/pdf.sandbox.js.map


文件差異過大導致無法顯示
+ 0 - 0
build/pdf.sandbox.min.js


文件差異過大導致無法顯示
+ 132 - 233
build/pdf.worker.js


文件差異過大導致無法顯示
+ 0 - 0
build/pdf.worker.js.map


文件差異過大導致無法顯示
+ 0 - 0
build/pdf.worker.min.js


+ 5 - 5
image_decoders/pdf.image_decoders.js

@@ -2619,7 +2619,7 @@ class SimpleSegmentVisitor {
   }
 
   onImmediateLosslessGenericRegion() {
-    this.onImmediateGenericRegion.apply(this, arguments);
+    this.onImmediateGenericRegion(...arguments);
   }
 
   onSymbolDictionary(dictionary, currentSegment, referredSegments, data, start, end) {
@@ -2677,7 +2677,7 @@ class SimpleSegmentVisitor {
   }
 
   onImmediateLosslessTextRegion() {
-    this.onImmediateTextRegion.apply(this, arguments);
+    this.onImmediateTextRegion(...arguments);
   }
 
   onPatternDictionary(dictionary, currentSegment, data, start, end) {
@@ -2700,7 +2700,7 @@ class SimpleSegmentVisitor {
   }
 
   onImmediateLosslessHalftoneRegion() {
-    this.onImmediateHalftoneRegion.apply(this, arguments);
+    this.onImmediateHalftoneRegion(...arguments);
   }
 
   onTables(currentSegment, data, start, end) {
@@ -9028,8 +9028,8 @@ var _jpg = __w_pdfjs_require__(10);
 
 var _jpx = __w_pdfjs_require__(11);
 
-const pdfjsVersion = '2.15.349';
-const pdfjsBuild = 'b8aa9c622';
+const pdfjsVersion = '2.16.105';
+const pdfjsBuild = '172ccdbe5';
 })();
 
 /******/ 	return __webpack_exports__;

文件差異過大導致無法顯示
+ 0 - 0
image_decoders/pdf.image_decoders.js.map


文件差異過大導致無法顯示
+ 0 - 0
image_decoders/pdf.image_decoders.min.js


文件差異過大導致無法顯示
+ 286 - 433
legacy/build/pdf.js


文件差異過大導致無法顯示
+ 0 - 0
legacy/build/pdf.js.map


文件差異過大導致無法顯示
+ 0 - 0
legacy/build/pdf.min.js


文件差異過大導致無法顯示
+ 0 - 0
legacy/build/pdf.sandbox.js


文件差異過大導致無法顯示
+ 0 - 0
legacy/build/pdf.sandbox.js.map


文件差異過大導致無法顯示
+ 0 - 0
legacy/build/pdf.sandbox.min.js


文件差異過大導致無法顯示
+ 0 - 2
legacy/build/pdf.worker.js


文件差異過大導致無法顯示
+ 0 - 0
legacy/build/pdf.worker.js.map


文件差異過大導致無法顯示
+ 0 - 0
legacy/build/pdf.worker.min.js


文件差異過大導致無法顯示
+ 276 - 423
legacy/image_decoders/pdf.image_decoders.js


文件差異過大導致無法顯示
+ 0 - 0
legacy/image_decoders/pdf.image_decoders.js.map


文件差異過大導致無法顯示
+ 0 - 0
legacy/image_decoders/pdf.image_decoders.min.js


+ 19 - 3
legacy/web/pdf_viewer.css

@@ -306,7 +306,6 @@
 
 .annotationLayer .popup {
   position: absolute;
-  z-index: 200;
   max-width: calc(180px * var(--scale-factor));
   background-color: rgba(255, 255, 153, 1);
   box-shadow: 0 calc(2px * var(--scale-factor)) calc(5px * var(--scale-factor))
@@ -368,6 +367,23 @@
   height: 100%;
 }
 
+.annotationLayer .annotationTextContent {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  opacity: 0;
+  color: transparent;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+          user-select: none;
+  pointer-events: none;
+}
+
+.annotationLayer .annotationTextContent span {
+  width: 100%;
+  display: inline-block;
+}
+
 
 :root {
   --xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,<svg width='1px' height='1px' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' style='fill:rgba(0, 54, 255, 0.13);'/></svg>");
@@ -707,11 +723,11 @@
 
 
 :root {
-  --focus-outline: solid 2px red;
+  --focus-outline: solid 2px blue;
   --hover-outline: dashed 2px blue;
   --freetext-line-height: 1.35;
   --freetext-padding: 2px;
-  --editorInk-editing-cursor: url(images/toolbarButton-editorInk.svg) 0 16;
+  --editorInk-editing-cursor: pointer;
 }
 
 @media (forced-colors: active) {

文件差異過大導致無法顯示
+ 99 - 144
legacy/web/pdf_viewer.js


文件差異過大導致無法顯示
+ 0 - 0
legacy/web/pdf_viewer.js.map


+ 57 - 3
lib/core/annotation.js

@@ -24,7 +24,7 @@
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.MarkupAnnotation = exports.AnnotationFactory = exports.AnnotationBorderStyle = exports.Annotation = void 0;
+exports.PopupAnnotation = exports.MarkupAnnotation = exports.AnnotationFactory = exports.AnnotationBorderStyle = exports.Annotation = void 0;
 exports.getQuadPoints = getQuadPoints;
 
 var _util = require("../shared/util.js");
@@ -722,6 +722,54 @@ class Annotation {
     return null;
   }
 
+  get hasTextContent() {
+    return false;
+  }
+
+  async extractTextContent(evaluator, task, viewBox) {
+    if (!this.appearance) {
+      return;
+    }
+
+    const resources = await this.loadResources(["ExtGState", "Font", "Properties", "XObject"], this.appearance);
+    const text = [];
+    const buffer = [];
+    const sink = {
+      desiredSize: Math.Infinity,
+      ready: true,
+
+      enqueue(chunk, size) {
+        for (const item of chunk.items) {
+          buffer.push(item.str);
+
+          if (item.hasEOL) {
+            text.push(buffer.join(""));
+            buffer.length = 0;
+          }
+        }
+      }
+
+    };
+    await evaluator.getTextContent({
+      stream: this.appearance,
+      task,
+      resources,
+      includeMarkedContent: true,
+      combineTextItems: true,
+      sink,
+      viewBox
+    });
+    this.reset();
+
+    if (buffer.length) {
+      text.push(buffer.join(""));
+    }
+
+    if (text.length > 0) {
+      this.data.textContent = text;
+    }
+  }
+
   getFieldObject() {
     if (this.data.kidIds) {
       return {
@@ -1711,12 +1759,12 @@ class TextWidgetAnnotation extends WidgetAnnotation {
     });
 
     if (!Number.isInteger(maximumLength) || maximumLength < 0) {
-      maximumLength = null;
+      maximumLength = 0;
     }
 
     this.data.maxLen = maximumLength;
     this.data.multiLine = this.hasFieldFlag(_util.AnnotationFieldFlag.MULTILINE);
-    this.data.comb = this.hasFieldFlag(_util.AnnotationFieldFlag.COMB) && !this.hasFieldFlag(_util.AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(_util.AnnotationFieldFlag.FILESELECT) && this.data.maxLen !== null;
+    this.data.comb = this.hasFieldFlag(_util.AnnotationFieldFlag.COMB) && !this.hasFieldFlag(_util.AnnotationFieldFlag.MULTILINE) && !this.hasFieldFlag(_util.AnnotationFieldFlag.PASSWORD) && !this.hasFieldFlag(_util.AnnotationFieldFlag.FILESELECT) && this.data.maxLen !== 0;
     this.data.doNotScroll = this.hasFieldFlag(_util.AnnotationFieldFlag.DONOTSCROLL);
   }
 
@@ -2607,12 +2655,18 @@ class PopupAnnotation extends Annotation {
 
 }
 
+exports.PopupAnnotation = PopupAnnotation;
+
 class FreeTextAnnotation extends MarkupAnnotation {
   constructor(parameters) {
     super(parameters);
     this.data.annotationType = _util.AnnotationType.FREETEXT;
   }
 
+  get hasTextContent() {
+    return !!this.appearance;
+  }
+
   static createNewDict(annotation, xref, {
     apRef,
     ap

文件差異過大導致無法顯示
+ 0 - 0
lib/core/cff_parser.js


+ 69 - 17
lib/core/document.js

@@ -26,6 +26,8 @@ Object.defineProperty(exports, "__esModule", {
 });
 exports.Page = exports.PDFDocument = void 0;
 
+var _annotation = require("./annotation.js");
+
 var _util = require("../shared/util.js");
 
 var _core_utils = require("./core_utils.js");
@@ -34,8 +36,6 @@ var _primitives = require("./primitives.js");
 
 var _xfa_fonts = require("./xfa_fonts.js");
 
-var _annotation = require("./annotation.js");
-
 var _base_stream = require("./base_stream.js");
 
 var _crypto = require("./crypto.js");
@@ -498,26 +498,50 @@ class Page {
     return tree;
   }
 
-  getAnnotationsData(intent) {
-    return this._parsedAnnotations.then(function (annotations) {
-      const annotationsData = [];
+  async getAnnotationsData(handler, task, intent) {
+    const annotations = await this._parsedAnnotations;
 
-      if (annotations.length === 0) {
-        return annotationsData;
-      }
+    if (annotations.length === 0) {
+      return [];
+    }
 
-      const intentAny = !!(intent & _util.RenderingIntentFlag.ANY),
-            intentDisplay = !!(intent & _util.RenderingIntentFlag.DISPLAY),
-            intentPrint = !!(intent & _util.RenderingIntentFlag.PRINT);
+    const textContentPromises = [];
+    const annotationsData = [];
+    let partialEvaluator;
+    const intentAny = !!(intent & _util.RenderingIntentFlag.ANY),
+          intentDisplay = !!(intent & _util.RenderingIntentFlag.DISPLAY),
+          intentPrint = !!(intent & _util.RenderingIntentFlag.PRINT);
 
-      for (const annotation of annotations) {
-        if (intentAny || intentDisplay && annotation.viewable || intentPrint && annotation.printable) {
-          annotationsData.push(annotation.data);
+    for (const annotation of annotations) {
+      const isVisible = intentAny || intentDisplay && annotation.viewable;
+
+      if (isVisible || intentPrint && annotation.printable) {
+        annotationsData.push(annotation.data);
+      }
+
+      if (annotation.hasTextContent && isVisible) {
+        if (!partialEvaluator) {
+          partialEvaluator = new _evaluator.PartialEvaluator({
+            xref: this.xref,
+            handler,
+            pageIndex: this.pageIndex,
+            idFactory: this._localIdFactory,
+            fontCache: this.fontCache,
+            builtInCMapCache: this.builtInCMapCache,
+            standardFontDataCache: this.standardFontDataCache,
+            globalImageCache: this.globalImageCache,
+            options: this.evaluatorOptions
+          });
         }
+
+        textContentPromises.push(annotation.extractTextContent(partialEvaluator, task, this.view).catch(function (reason) {
+          (0, _util.warn)(`getAnnotationsData - ignoring textContent during "${task.name}" task: "${reason}".`);
+        }));
       }
+    }
 
-      return annotationsData;
-    });
+    await Promise.all(textContentPromises);
+    return annotationsData;
   }
 
   get annotations() {
@@ -538,7 +562,35 @@ class Page {
       }
 
       return Promise.all(annotationPromises).then(function (annotations) {
-        return annotations.filter(annotation => !!annotation);
+        if (annotations.length === 0) {
+          return annotations;
+        }
+
+        const sortedAnnotations = [];
+        let popupAnnotations;
+
+        for (const annotation of annotations) {
+          if (!annotation) {
+            continue;
+          }
+
+          if (annotation instanceof _annotation.PopupAnnotation) {
+            if (!popupAnnotations) {
+              popupAnnotations = [];
+            }
+
+            popupAnnotations.push(annotation);
+            continue;
+          }
+
+          sortedAnnotations.push(annotation);
+        }
+
+        if (popupAnnotations) {
+          sortedAnnotations.push(...popupAnnotations);
+        }
+
+        return sortedAnnotations;
       });
     });
     return (0, _util.shadow)(this, "_parsedAnnotations", parsedAnnotations);

+ 1 - 1
lib/core/evaluator.js

@@ -3206,7 +3206,7 @@ class PartialEvaluator {
             str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000);
           }
 
-          map[charCode] = String.fromCodePoint.apply(String, str);
+          map[charCode] = String.fromCodePoint(...str);
         });
         return new _to_unicode_map.ToUnicodeMap(map);
       }, reason => {

+ 307 - 311
lib/core/function.js

@@ -933,421 +933,417 @@ class PostScriptEvaluator {
 
 exports.PostScriptEvaluator = PostScriptEvaluator;
 
-const PostScriptCompiler = function PostScriptCompilerClosure() {
-  class AstNode {
-    constructor(type) {
-      this.type = type;
-    }
+class AstNode {
+  constructor(type) {
+    this.type = type;
+  }
 
-    visit(visitor) {
-      (0, _util.unreachable)("abstract method");
-    }
+  visit(visitor) {
+    (0, _util.unreachable)("abstract method");
+  }
+
+}
 
+class AstArgument extends AstNode {
+  constructor(index, min, max) {
+    super("args");
+    this.index = index;
+    this.min = min;
+    this.max = max;
   }
 
-  class AstArgument extends AstNode {
-    constructor(index, min, max) {
-      super("args");
-      this.index = index;
-      this.min = min;
-      this.max = max;
-    }
+  visit(visitor) {
+    visitor.visitArgument(this);
+  }
 
-    visit(visitor) {
-      visitor.visitArgument(this);
-    }
+}
 
+class AstLiteral extends AstNode {
+  constructor(number) {
+    super("literal");
+    this.number = number;
+    this.min = number;
+    this.max = number;
   }
 
-  class AstLiteral extends AstNode {
-    constructor(number) {
-      super("literal");
-      this.number = number;
-      this.min = number;
-      this.max = number;
-    }
+  visit(visitor) {
+    visitor.visitLiteral(this);
+  }
 
-    visit(visitor) {
-      visitor.visitLiteral(this);
-    }
+}
 
+class AstBinaryOperation extends AstNode {
+  constructor(op, arg1, arg2, min, max) {
+    super("binary");
+    this.op = op;
+    this.arg1 = arg1;
+    this.arg2 = arg2;
+    this.min = min;
+    this.max = max;
   }
 
-  class AstBinaryOperation extends AstNode {
-    constructor(op, arg1, arg2, min, max) {
-      super("binary");
-      this.op = op;
-      this.arg1 = arg1;
-      this.arg2 = arg2;
-      this.min = min;
-      this.max = max;
-    }
+  visit(visitor) {
+    visitor.visitBinaryOperation(this);
+  }
 
-    visit(visitor) {
-      visitor.visitBinaryOperation(this);
-    }
+}
 
+class AstMin extends AstNode {
+  constructor(arg, max) {
+    super("max");
+    this.arg = arg;
+    this.min = arg.min;
+    this.max = max;
   }
 
-  class AstMin extends AstNode {
-    constructor(arg, max) {
-      super("max");
-      this.arg = arg;
-      this.min = arg.min;
-      this.max = max;
-    }
+  visit(visitor) {
+    visitor.visitMin(this);
+  }
 
-    visit(visitor) {
-      visitor.visitMin(this);
-    }
+}
 
+class AstVariable extends AstNode {
+  constructor(index, min, max) {
+    super("var");
+    this.index = index;
+    this.min = min;
+    this.max = max;
   }
 
-  class AstVariable extends AstNode {
-    constructor(index, min, max) {
-      super("var");
-      this.index = index;
-      this.min = min;
-      this.max = max;
-    }
+  visit(visitor) {
+    visitor.visitVariable(this);
+  }
 
-    visit(visitor) {
-      visitor.visitVariable(this);
-    }
+}
 
+class AstVariableDefinition extends AstNode {
+  constructor(variable, arg) {
+    super("definition");
+    this.variable = variable;
+    this.arg = arg;
   }
 
-  class AstVariableDefinition extends AstNode {
-    constructor(variable, arg) {
-      super("definition");
-      this.variable = variable;
-      this.arg = arg;
-    }
+  visit(visitor) {
+    visitor.visitVariableDefinition(this);
+  }
 
-    visit(visitor) {
-      visitor.visitVariableDefinition(this);
-    }
+}
 
+class ExpressionBuilderVisitor {
+  constructor() {
+    this.parts = [];
   }
 
-  class ExpressionBuilderVisitor {
-    constructor() {
-      this.parts = [];
-    }
+  visitArgument(arg) {
+    this.parts.push("Math.max(", arg.min, ", Math.min(", arg.max, ", src[srcOffset + ", arg.index, "]))");
+  }
 
-    visitArgument(arg) {
-      this.parts.push("Math.max(", arg.min, ", Math.min(", arg.max, ", src[srcOffset + ", arg.index, "]))");
-    }
+  visitVariable(variable) {
+    this.parts.push("v", variable.index);
+  }
 
-    visitVariable(variable) {
-      this.parts.push("v", variable.index);
-    }
+  visitLiteral(literal) {
+    this.parts.push(literal.number);
+  }
 
-    visitLiteral(literal) {
-      this.parts.push(literal.number);
-    }
+  visitBinaryOperation(operation) {
+    this.parts.push("(");
+    operation.arg1.visit(this);
+    this.parts.push(" ", operation.op, " ");
+    operation.arg2.visit(this);
+    this.parts.push(")");
+  }
 
-    visitBinaryOperation(operation) {
-      this.parts.push("(");
-      operation.arg1.visit(this);
-      this.parts.push(" ", operation.op, " ");
-      operation.arg2.visit(this);
-      this.parts.push(")");
-    }
+  visitVariableDefinition(definition) {
+    this.parts.push("var ");
+    definition.variable.visit(this);
+    this.parts.push(" = ");
+    definition.arg.visit(this);
+    this.parts.push(";");
+  }
 
-    visitVariableDefinition(definition) {
-      this.parts.push("var ");
-      definition.variable.visit(this);
-      this.parts.push(" = ");
-      definition.arg.visit(this);
-      this.parts.push(";");
-    }
+  visitMin(max) {
+    this.parts.push("Math.min(");
+    max.arg.visit(this);
+    this.parts.push(", ", max.max, ")");
+  }
 
-    visitMin(max) {
-      this.parts.push("Math.min(");
-      max.arg.visit(this);
-      this.parts.push(", ", max.max, ")");
-    }
+  toString() {
+    return this.parts.join("");
+  }
 
-    toString() {
-      return this.parts.join("");
-    }
+}
+
+function buildAddOperation(num1, num2) {
+  if (num2.type === "literal" && num2.number === 0) {
+    return num1;
+  }
 
+  if (num1.type === "literal" && num1.number === 0) {
+    return num2;
   }
 
-  function buildAddOperation(num1, num2) {
-    if (num2.type === "literal" && num2.number === 0) {
+  if (num2.type === "literal" && num1.type === "literal") {
+    return new AstLiteral(num1.number + num2.number);
+  }
+
+  return new AstBinaryOperation("+", num1, num2, num1.min + num2.min, num1.max + num2.max);
+}
+
+function buildMulOperation(num1, num2) {
+  if (num2.type === "literal") {
+    if (num2.number === 0) {
+      return new AstLiteral(0);
+    } else if (num2.number === 1) {
       return num1;
+    } else if (num1.type === "literal") {
+      return new AstLiteral(num1.number * num2.number);
     }
+  }
 
-    if (num1.type === "literal" && num1.number === 0) {
+  if (num1.type === "literal") {
+    if (num1.number === 0) {
+      return new AstLiteral(0);
+    } else if (num1.number === 1) {
       return num2;
     }
-
-    if (num2.type === "literal" && num1.type === "literal") {
-      return new AstLiteral(num1.number + num2.number);
-    }
-
-    return new AstBinaryOperation("+", num1, num2, num1.min + num2.min, num1.max + num2.max);
   }
 
-  function buildMulOperation(num1, num2) {
-    if (num2.type === "literal") {
-      if (num2.number === 0) {
-        return new AstLiteral(0);
-      } else if (num2.number === 1) {
-        return num1;
-      } else if (num1.type === "literal") {
-        return new AstLiteral(num1.number * num2.number);
-      }
-    }
+  const min = Math.min(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max);
+  const max = Math.max(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max);
+  return new AstBinaryOperation("*", num1, num2, min, max);
+}
 
-    if (num1.type === "literal") {
-      if (num1.number === 0) {
-        return new AstLiteral(0);
-      } else if (num1.number === 1) {
-        return num2;
-      }
+function buildSubOperation(num1, num2) {
+  if (num2.type === "literal") {
+    if (num2.number === 0) {
+      return num1;
+    } else if (num1.type === "literal") {
+      return new AstLiteral(num1.number - num2.number);
     }
-
-    const min = Math.min(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max);
-    const max = Math.max(num1.min * num2.min, num1.min * num2.max, num1.max * num2.min, num1.max * num2.max);
-    return new AstBinaryOperation("*", num1, num2, min, max);
   }
 
-  function buildSubOperation(num1, num2) {
-    if (num2.type === "literal") {
-      if (num2.number === 0) {
-        return num1;
-      } else if (num1.type === "literal") {
-        return new AstLiteral(num1.number - num2.number);
-      }
-    }
+  if (num2.type === "binary" && num2.op === "-" && num1.type === "literal" && num1.number === 1 && num2.arg1.type === "literal" && num2.arg1.number === 1) {
+    return num2.arg2;
+  }
 
-    if (num2.type === "binary" && num2.op === "-" && num1.type === "literal" && num1.number === 1 && num2.arg1.type === "literal" && num2.arg1.number === 1) {
-      return num2.arg2;
-    }
+  return new AstBinaryOperation("-", num1, num2, num1.min - num2.max, num1.max - num2.min);
+}
 
-    return new AstBinaryOperation("-", num1, num2, num1.min - num2.max, num1.max - num2.min);
+function buildMinOperation(num1, max) {
+  if (num1.min >= max) {
+    return new AstLiteral(max);
+  } else if (num1.max <= max) {
+    return num1;
   }
 
-  function buildMinOperation(num1, max) {
-    if (num1.min >= max) {
-      return new AstLiteral(max);
-    } else if (num1.max <= max) {
-      return num1;
+  return new AstMin(num1, max);
+}
+
+class PostScriptCompiler {
+  compile(code, domain, range) {
+    const stack = [];
+    const instructions = [];
+    const inputSize = domain.length >> 1,
+          outputSize = range.length >> 1;
+    let lastRegister = 0;
+    let n, j;
+    let num1, num2, ast1, ast2, tmpVar, item;
+
+    for (let i = 0; i < inputSize; i++) {
+      stack.push(new AstArgument(i, domain[i * 2], domain[i * 2 + 1]));
     }
 
-    return new AstMin(num1, max);
-  }
+    for (let i = 0, ii = code.length; i < ii; i++) {
+      item = code[i];
 
-  class PostScriptCompiler {
-    compile(code, domain, range) {
-      const stack = [];
-      const instructions = [];
-      const inputSize = domain.length >> 1,
-            outputSize = range.length >> 1;
-      let lastRegister = 0;
-      let n, j;
-      let num1, num2, ast1, ast2, tmpVar, item;
-
-      for (let i = 0; i < inputSize; i++) {
-        stack.push(new AstArgument(i, domain[i * 2], domain[i * 2 + 1]));
+      if (typeof item === "number") {
+        stack.push(new AstLiteral(item));
+        continue;
       }
 
-      for (let i = 0, ii = code.length; i < ii; i++) {
-        item = code[i];
+      switch (item) {
+        case "add":
+          if (stack.length < 2) {
+            return null;
+          }
 
-        if (typeof item === "number") {
-          stack.push(new AstLiteral(item));
-          continue;
-        }
+          num2 = stack.pop();
+          num1 = stack.pop();
+          stack.push(buildAddOperation(num1, num2));
+          break;
 
-        switch (item) {
-          case "add":
-            if (stack.length < 2) {
-              return null;
-            }
+        case "cvr":
+          if (stack.length < 1) {
+            return null;
+          }
 
-            num2 = stack.pop();
-            num1 = stack.pop();
-            stack.push(buildAddOperation(num1, num2));
-            break;
+          break;
 
-          case "cvr":
-            if (stack.length < 1) {
-              return null;
-            }
+        case "mul":
+          if (stack.length < 2) {
+            return null;
+          }
 
-            break;
+          num2 = stack.pop();
+          num1 = stack.pop();
+          stack.push(buildMulOperation(num1, num2));
+          break;
 
-          case "mul":
-            if (stack.length < 2) {
-              return null;
-            }
+        case "sub":
+          if (stack.length < 2) {
+            return null;
+          }
 
-            num2 = stack.pop();
-            num1 = stack.pop();
-            stack.push(buildMulOperation(num1, num2));
-            break;
+          num2 = stack.pop();
+          num1 = stack.pop();
+          stack.push(buildSubOperation(num1, num2));
+          break;
 
-          case "sub":
-            if (stack.length < 2) {
-              return null;
-            }
+        case "exch":
+          if (stack.length < 2) {
+            return null;
+          }
 
-            num2 = stack.pop();
-            num1 = stack.pop();
-            stack.push(buildSubOperation(num1, num2));
-            break;
+          ast1 = stack.pop();
+          ast2 = stack.pop();
+          stack.push(ast1, ast2);
+          break;
 
-          case "exch":
-            if (stack.length < 2) {
-              return null;
-            }
+        case "pop":
+          if (stack.length < 1) {
+            return null;
+          }
 
-            ast1 = stack.pop();
-            ast2 = stack.pop();
-            stack.push(ast1, ast2);
-            break;
+          stack.pop();
+          break;
 
-          case "pop":
-            if (stack.length < 1) {
-              return null;
-            }
+        case "index":
+          if (stack.length < 1) {
+            return null;
+          }
 
-            stack.pop();
-            break;
+          num1 = stack.pop();
 
-          case "index":
-            if (stack.length < 1) {
-              return null;
-            }
+          if (num1.type !== "literal") {
+            return null;
+          }
 
-            num1 = stack.pop();
+          n = num1.number;
 
-            if (num1.type !== "literal") {
-              return null;
-            }
+          if (n < 0 || !Number.isInteger(n) || stack.length < n) {
+            return null;
+          }
 
-            n = num1.number;
+          ast1 = stack[stack.length - n - 1];
 
-            if (n < 0 || !Number.isInteger(n) || stack.length < n) {
-              return null;
-            }
+          if (ast1.type === "literal" || ast1.type === "var") {
+            stack.push(ast1);
+            break;
+          }
 
-            ast1 = stack[stack.length - n - 1];
+          tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max);
+          stack[stack.length - n - 1] = tmpVar;
+          stack.push(tmpVar);
+          instructions.push(new AstVariableDefinition(tmpVar, ast1));
+          break;
 
-            if (ast1.type === "literal" || ast1.type === "var") {
-              stack.push(ast1);
-              break;
-            }
+        case "dup":
+          if (stack.length < 1) {
+            return null;
+          }
 
-            tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max);
-            stack[stack.length - n - 1] = tmpVar;
-            stack.push(tmpVar);
-            instructions.push(new AstVariableDefinition(tmpVar, ast1));
+          if (typeof code[i + 1] === "number" && code[i + 2] === "gt" && code[i + 3] === i + 7 && code[i + 4] === "jz" && code[i + 5] === "pop" && code[i + 6] === code[i + 1]) {
+            num1 = stack.pop();
+            stack.push(buildMinOperation(num1, code[i + 1]));
+            i += 6;
             break;
+          }
+
+          ast1 = stack.at(-1);
 
-          case "dup":
-            if (stack.length < 1) {
-              return null;
-            }
-
-            if (typeof code[i + 1] === "number" && code[i + 2] === "gt" && code[i + 3] === i + 7 && code[i + 4] === "jz" && code[i + 5] === "pop" && code[i + 6] === code[i + 1]) {
-              num1 = stack.pop();
-              stack.push(buildMinOperation(num1, code[i + 1]));
-              i += 6;
-              break;
-            }
-
-            ast1 = stack.at(-1);
-
-            if (ast1.type === "literal" || ast1.type === "var") {
-              stack.push(ast1);
-              break;
-            }
-
-            tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max);
-            stack[stack.length - 1] = tmpVar;
-            stack.push(tmpVar);
-            instructions.push(new AstVariableDefinition(tmpVar, ast1));
+          if (ast1.type === "literal" || ast1.type === "var") {
+            stack.push(ast1);
             break;
+          }
 
-          case "roll":
-            if (stack.length < 2) {
-              return null;
-            }
+          tmpVar = new AstVariable(lastRegister++, ast1.min, ast1.max);
+          stack[stack.length - 1] = tmpVar;
+          stack.push(tmpVar);
+          instructions.push(new AstVariableDefinition(tmpVar, ast1));
+          break;
 
-            num2 = stack.pop();
-            num1 = stack.pop();
+        case "roll":
+          if (stack.length < 2) {
+            return null;
+          }
 
-            if (num2.type !== "literal" || num1.type !== "literal") {
-              return null;
-            }
+          num2 = stack.pop();
+          num1 = stack.pop();
 
-            j = num2.number;
-            n = num1.number;
+          if (num2.type !== "literal" || num1.type !== "literal") {
+            return null;
+          }
 
-            if (n <= 0 || !Number.isInteger(n) || !Number.isInteger(j) || stack.length < n) {
-              return null;
-            }
+          j = num2.number;
+          n = num1.number;
 
-            j = (j % n + n) % n;
+          if (n <= 0 || !Number.isInteger(n) || !Number.isInteger(j) || stack.length < n) {
+            return null;
+          }
 
-            if (j === 0) {
-              break;
-            }
+          j = (j % n + n) % n;
 
-            Array.prototype.push.apply(stack, stack.splice(stack.length - n, n - j));
+          if (j === 0) {
             break;
+          }
 
-          default:
-            return null;
-        }
-      }
+          Array.prototype.push.apply(stack, stack.splice(stack.length - n, n - j));
+          break;
 
-      if (stack.length !== outputSize) {
-        return null;
+        default:
+          return null;
       }
+    }
 
-      const result = [];
+    if (stack.length !== outputSize) {
+      return null;
+    }
 
-      for (const instruction of instructions) {
-        const statementBuilder = new ExpressionBuilderVisitor();
-        instruction.visit(statementBuilder);
-        result.push(statementBuilder.toString());
-      }
+    const result = [];
 
-      for (let i = 0, ii = stack.length; i < ii; i++) {
-        const expr = stack[i],
-              statementBuilder = new ExpressionBuilderVisitor();
-        expr.visit(statementBuilder);
-        const min = range[i * 2],
-              max = range[i * 2 + 1];
-        const out = [statementBuilder.toString()];
-
-        if (min > expr.min) {
-          out.unshift("Math.max(", min, ", ");
-          out.push(")");
-        }
+    for (const instruction of instructions) {
+      const statementBuilder = new ExpressionBuilderVisitor();
+      instruction.visit(statementBuilder);
+      result.push(statementBuilder.toString());
+    }
 
-        if (max < expr.max) {
-          out.unshift("Math.min(", max, ", ");
-          out.push(")");
-        }
+    for (let i = 0, ii = stack.length; i < ii; i++) {
+      const expr = stack[i],
+            statementBuilder = new ExpressionBuilderVisitor();
+      expr.visit(statementBuilder);
+      const min = range[i * 2],
+            max = range[i * 2 + 1];
+      const out = [statementBuilder.toString()];
+
+      if (min > expr.min) {
+        out.unshift("Math.max(", min, ", ");
+        out.push(")");
+      }
 
-        out.unshift("dest[destOffset + ", i, "] = ");
-        out.push(";");
-        result.push(out.join(""));
+      if (max < expr.max) {
+        out.unshift("Math.min(", max, ", ");
+        out.push(")");
       }
 
-      return result.join("\n");
+      out.unshift("dest[destOffset + ", i, "] = ");
+      out.push(";");
+      result.push(out.join(""));
     }
 
+    return result.join("\n");
   }
 
-  return PostScriptCompiler;
-}();
+}
 
 exports.PostScriptCompiler = PostScriptCompiler;

+ 3 - 3
lib/core/jbig2.js

@@ -1486,7 +1486,7 @@ class SimpleSegmentVisitor {
   }
 
   onImmediateLosslessGenericRegion() {
-    this.onImmediateGenericRegion.apply(this, arguments);
+    this.onImmediateGenericRegion(...arguments);
   }
 
   onSymbolDictionary(dictionary, currentSegment, referredSegments, data, start, end) {
@@ -1544,7 +1544,7 @@ class SimpleSegmentVisitor {
   }
 
   onImmediateLosslessTextRegion() {
-    this.onImmediateTextRegion.apply(this, arguments);
+    this.onImmediateTextRegion(...arguments);
   }
 
   onPatternDictionary(dictionary, currentSegment, data, start, end) {
@@ -1567,7 +1567,7 @@ class SimpleSegmentVisitor {
   }
 
   onImmediateLosslessHalftoneRegion() {
-    this.onImmediateHalftoneRegion.apply(this, arguments);
+    this.onImmediateHalftoneRegion(...arguments);
   }
 
   onTables(currentSegment, data, start, end) {

+ 521 - 530
lib/core/type1_parser.js

@@ -35,713 +35,704 @@ var _stream = require("./stream.js");
 var _util = require("../shared/util.js");
 
 const HINTING_ENABLED = false;
+const COMMAND_MAP = {
+  hstem: [1],
+  vstem: [3],
+  vmoveto: [4],
+  rlineto: [5],
+  hlineto: [6],
+  vlineto: [7],
+  rrcurveto: [8],
+  callsubr: [10],
+  flex: [12, 35],
+  drop: [12, 18],
+  endchar: [14],
+  rmoveto: [21],
+  hmoveto: [22],
+  vhcurveto: [30],
+  hvcurveto: [31]
+};
+
+class Type1CharString {
+  constructor() {
+    this.width = 0;
+    this.lsb = 0;
+    this.flexing = false;
+    this.output = [];
+    this.stack = [];
+  }
 
-const Type1CharString = function Type1CharStringClosure() {
-  const COMMAND_MAP = {
-    hstem: [1],
-    vstem: [3],
-    vmoveto: [4],
-    rlineto: [5],
-    hlineto: [6],
-    vlineto: [7],
-    rrcurveto: [8],
-    callsubr: [10],
-    flex: [12, 35],
-    drop: [12, 18],
-    endchar: [14],
-    rmoveto: [21],
-    hmoveto: [22],
-    vhcurveto: [30],
-    hvcurveto: [31]
-  };
-
-  class Type1CharString {
-    constructor() {
-      this.width = 0;
-      this.lsb = 0;
-      this.flexing = false;
-      this.output = [];
-      this.stack = [];
-    }
-
-    convert(encoded, subrs, seacAnalysisEnabled) {
-      const count = encoded.length;
-      let error = false;
-      let wx, sbx, subrNumber;
-
-      for (let i = 0; i < count; i++) {
-        let value = encoded[i];
+  convert(encoded, subrs, seacAnalysisEnabled) {
+    const count = encoded.length;
+    let error = false;
+    let wx, sbx, subrNumber;
 
-        if (value < 32) {
-          if (value === 12) {
-            value = (value << 8) + encoded[++i];
-          }
+    for (let i = 0; i < count; i++) {
+      let value = encoded[i];
 
-          switch (value) {
-            case 1:
-              if (!HINTING_ENABLED) {
-                this.stack = [];
-                break;
-              }
+      if (value < 32) {
+        if (value === 12) {
+          value = (value << 8) + encoded[++i];
+        }
 
-              error = this.executeCommand(2, COMMAND_MAP.hstem);
+        switch (value) {
+          case 1:
+            if (!HINTING_ENABLED) {
+              this.stack = [];
               break;
+            }
 
-            case 3:
-              if (!HINTING_ENABLED) {
-                this.stack = [];
-                break;
-              }
+            error = this.executeCommand(2, COMMAND_MAP.hstem);
+            break;
 
-              error = this.executeCommand(2, COMMAND_MAP.vstem);
+          case 3:
+            if (!HINTING_ENABLED) {
+              this.stack = [];
               break;
+            }
 
-            case 4:
-              if (this.flexing) {
-                if (this.stack.length < 1) {
-                  error = true;
-                  break;
-                }
+            error = this.executeCommand(2, COMMAND_MAP.vstem);
+            break;
 
-                const dy = this.stack.pop();
-                this.stack.push(0, dy);
+          case 4:
+            if (this.flexing) {
+              if (this.stack.length < 1) {
+                error = true;
                 break;
               }
 
-              error = this.executeCommand(1, COMMAND_MAP.vmoveto);
+              const dy = this.stack.pop();
+              this.stack.push(0, dy);
               break;
+            }
 
-            case 5:
-              error = this.executeCommand(2, COMMAND_MAP.rlineto);
-              break;
+            error = this.executeCommand(1, COMMAND_MAP.vmoveto);
+            break;
 
-            case 6:
-              error = this.executeCommand(1, COMMAND_MAP.hlineto);
-              break;
+          case 5:
+            error = this.executeCommand(2, COMMAND_MAP.rlineto);
+            break;
 
-            case 7:
-              error = this.executeCommand(1, COMMAND_MAP.vlineto);
-              break;
+          case 6:
+            error = this.executeCommand(1, COMMAND_MAP.hlineto);
+            break;
 
-            case 8:
-              error = this.executeCommand(6, COMMAND_MAP.rrcurveto);
-              break;
+          case 7:
+            error = this.executeCommand(1, COMMAND_MAP.vlineto);
+            break;
 
-            case 9:
-              this.stack = [];
-              break;
+          case 8:
+            error = this.executeCommand(6, COMMAND_MAP.rrcurveto);
+            break;
 
-            case 10:
-              if (this.stack.length < 1) {
-                error = true;
-                break;
-              }
+          case 9:
+            this.stack = [];
+            break;
 
-              subrNumber = this.stack.pop();
+          case 10:
+            if (this.stack.length < 1) {
+              error = true;
+              break;
+            }
 
-              if (!subrs[subrNumber]) {
-                error = true;
-                break;
-              }
+            subrNumber = this.stack.pop();
 
-              error = this.convert(subrs[subrNumber], subrs, seacAnalysisEnabled);
+            if (!subrs[subrNumber]) {
+              error = true;
               break;
+            }
 
-            case 11:
-              return error;
+            error = this.convert(subrs[subrNumber], subrs, seacAnalysisEnabled);
+            break;
 
-            case 13:
-              if (this.stack.length < 2) {
-                error = true;
-                break;
-              }
+          case 11:
+            return error;
 
-              wx = this.stack.pop();
-              sbx = this.stack.pop();
-              this.lsb = sbx;
-              this.width = wx;
-              this.stack.push(wx, sbx);
-              error = this.executeCommand(2, COMMAND_MAP.hmoveto);
+          case 13:
+            if (this.stack.length < 2) {
+              error = true;
               break;
+            }
 
-            case 14:
-              this.output.push(COMMAND_MAP.endchar[0]);
-              break;
+            wx = this.stack.pop();
+            sbx = this.stack.pop();
+            this.lsb = sbx;
+            this.width = wx;
+            this.stack.push(wx, sbx);
+            error = this.executeCommand(2, COMMAND_MAP.hmoveto);
+            break;
 
-            case 21:
-              if (this.flexing) {
-                break;
-              }
+          case 14:
+            this.output.push(COMMAND_MAP.endchar[0]);
+            break;
 
-              error = this.executeCommand(2, COMMAND_MAP.rmoveto);
+          case 21:
+            if (this.flexing) {
               break;
+            }
 
-            case 22:
-              if (this.flexing) {
-                this.stack.push(0);
-                break;
-              }
+            error = this.executeCommand(2, COMMAND_MAP.rmoveto);
+            break;
 
-              error = this.executeCommand(1, COMMAND_MAP.hmoveto);
+          case 22:
+            if (this.flexing) {
+              this.stack.push(0);
               break;
+            }
 
-            case 30:
-              error = this.executeCommand(4, COMMAND_MAP.vhcurveto);
-              break;
+            error = this.executeCommand(1, COMMAND_MAP.hmoveto);
+            break;
 
-            case 31:
-              error = this.executeCommand(4, COMMAND_MAP.hvcurveto);
-              break;
+          case 30:
+            error = this.executeCommand(4, COMMAND_MAP.vhcurveto);
+            break;
 
-            case (12 << 8) + 0:
-              this.stack = [];
-              break;
+          case 31:
+            error = this.executeCommand(4, COMMAND_MAP.hvcurveto);
+            break;
 
-            case (12 << 8) + 1:
-              if (!HINTING_ENABLED) {
-                this.stack = [];
-                break;
-              }
+          case (12 << 8) + 0:
+            this.stack = [];
+            break;
 
-              error = this.executeCommand(2, COMMAND_MAP.vstem);
+          case (12 << 8) + 1:
+            if (!HINTING_ENABLED) {
+              this.stack = [];
               break;
+            }
 
-            case (12 << 8) + 2:
-              if (!HINTING_ENABLED) {
-                this.stack = [];
-                break;
-              }
+            error = this.executeCommand(2, COMMAND_MAP.vstem);
+            break;
 
-              error = this.executeCommand(2, COMMAND_MAP.hstem);
+          case (12 << 8) + 2:
+            if (!HINTING_ENABLED) {
+              this.stack = [];
               break;
+            }
 
-            case (12 << 8) + 6:
-              if (seacAnalysisEnabled) {
-                const asb = this.stack.at(-5);
-                this.seac = this.stack.splice(-4, 4);
-                this.seac[0] += this.lsb - asb;
-                error = this.executeCommand(0, COMMAND_MAP.endchar);
-              } else {
-                error = this.executeCommand(4, COMMAND_MAP.endchar);
-              }
+            error = this.executeCommand(2, COMMAND_MAP.hstem);
+            break;
 
-              break;
+          case (12 << 8) + 6:
+            if (seacAnalysisEnabled) {
+              const asb = this.stack.at(-5);
+              this.seac = this.stack.splice(-4, 4);
+              this.seac[0] += this.lsb - asb;
+              error = this.executeCommand(0, COMMAND_MAP.endchar);
+            } else {
+              error = this.executeCommand(4, COMMAND_MAP.endchar);
+            }
 
-            case (12 << 8) + 7:
-              if (this.stack.length < 4) {
-                error = true;
-                break;
-              }
+            break;
 
-              this.stack.pop();
-              wx = this.stack.pop();
-              const sby = this.stack.pop();
-              sbx = this.stack.pop();
-              this.lsb = sbx;
-              this.width = wx;
-              this.stack.push(wx, sbx, sby);
-              error = this.executeCommand(3, COMMAND_MAP.rmoveto);
+          case (12 << 8) + 7:
+            if (this.stack.length < 4) {
+              error = true;
               break;
+            }
 
-            case (12 << 8) + 12:
-              if (this.stack.length < 2) {
-                error = true;
-                break;
-              }
+            this.stack.pop();
+            wx = this.stack.pop();
+            const sby = this.stack.pop();
+            sbx = this.stack.pop();
+            this.lsb = sbx;
+            this.width = wx;
+            this.stack.push(wx, sbx, sby);
+            error = this.executeCommand(3, COMMAND_MAP.rmoveto);
+            break;
 
-              const num2 = this.stack.pop();
-              const num1 = this.stack.pop();
-              this.stack.push(num1 / num2);
+          case (12 << 8) + 12:
+            if (this.stack.length < 2) {
+              error = true;
               break;
+            }
 
-            case (12 << 8) + 16:
-              if (this.stack.length < 2) {
-                error = true;
-                break;
-              }
-
-              subrNumber = this.stack.pop();
-              const numArgs = this.stack.pop();
-
-              if (subrNumber === 0 && numArgs === 3) {
-                const flexArgs = this.stack.splice(this.stack.length - 17, 17);
-                this.stack.push(flexArgs[2] + flexArgs[0], flexArgs[3] + flexArgs[1], flexArgs[4], flexArgs[5], flexArgs[6], flexArgs[7], flexArgs[8], flexArgs[9], flexArgs[10], flexArgs[11], flexArgs[12], flexArgs[13], flexArgs[14]);
-                error = this.executeCommand(13, COMMAND_MAP.flex, true);
-                this.flexing = false;
-                this.stack.push(flexArgs[15], flexArgs[16]);
-              } else if (subrNumber === 1 && numArgs === 0) {
-                this.flexing = true;
-              }
+            const num2 = this.stack.pop();
+            const num1 = this.stack.pop();
+            this.stack.push(num1 / num2);
+            break;
 
+          case (12 << 8) + 16:
+            if (this.stack.length < 2) {
+              error = true;
               break;
+            }
 
-            case (12 << 8) + 17:
-              break;
+            subrNumber = this.stack.pop();
+            const numArgs = this.stack.pop();
+
+            if (subrNumber === 0 && numArgs === 3) {
+              const flexArgs = this.stack.splice(this.stack.length - 17, 17);
+              this.stack.push(flexArgs[2] + flexArgs[0], flexArgs[3] + flexArgs[1], flexArgs[4], flexArgs[5], flexArgs[6], flexArgs[7], flexArgs[8], flexArgs[9], flexArgs[10], flexArgs[11], flexArgs[12], flexArgs[13], flexArgs[14]);
+              error = this.executeCommand(13, COMMAND_MAP.flex, true);
+              this.flexing = false;
+              this.stack.push(flexArgs[15], flexArgs[16]);
+            } else if (subrNumber === 1 && numArgs === 0) {
+              this.flexing = true;
+            }
 
-            case (12 << 8) + 33:
-              this.stack = [];
-              break;
+            break;
 
-            default:
-              (0, _util.warn)('Unknown type 1 charstring command of "' + value + '"');
-              break;
-          }
+          case (12 << 8) + 17:
+            break;
 
-          if (error) {
+          case (12 << 8) + 33:
+            this.stack = [];
             break;
-          }
 
-          continue;
-        } else if (value <= 246) {
-          value -= 139;
-        } else if (value <= 250) {
-          value = (value - 247) * 256 + encoded[++i] + 108;
-        } else if (value <= 254) {
-          value = -((value - 251) * 256) - encoded[++i] - 108;
-        } else {
-          value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 | (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0;
+          default:
+            (0, _util.warn)('Unknown type 1 charstring command of "' + value + '"');
+            break;
+        }
+
+        if (error) {
+          break;
         }
 
-        this.stack.push(value);
+        continue;
+      } else if (value <= 246) {
+        value -= 139;
+      } else if (value <= 250) {
+        value = (value - 247) * 256 + encoded[++i] + 108;
+      } else if (value <= 254) {
+        value = -((value - 251) * 256) - encoded[++i] - 108;
+      } else {
+        value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 | (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0;
       }
 
-      return error;
+      this.stack.push(value);
     }
 
-    executeCommand(howManyArgs, command, keepStack) {
-      const stackLength = this.stack.length;
-
-      if (howManyArgs > stackLength) {
-        return true;
-      }
+    return error;
+  }
 
-      const start = stackLength - howManyArgs;
+  executeCommand(howManyArgs, command, keepStack) {
+    const stackLength = this.stack.length;
 
-      for (let i = start; i < stackLength; i++) {
-        let value = this.stack[i];
+    if (howManyArgs > stackLength) {
+      return true;
+    }
 
-        if (Number.isInteger(value)) {
-          this.output.push(28, value >> 8 & 0xff, value & 0xff);
-        } else {
-          value = 65536 * value | 0;
-          this.output.push(255, value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);
-        }
-      }
+    const start = stackLength - howManyArgs;
 
-      this.output.push.apply(this.output, command);
+    for (let i = start; i < stackLength; i++) {
+      let value = this.stack[i];
 
-      if (keepStack) {
-        this.stack.splice(start, howManyArgs);
+      if (Number.isInteger(value)) {
+        this.output.push(28, value >> 8 & 0xff, value & 0xff);
       } else {
-        this.stack.length = 0;
+        value = 65536 * value | 0;
+        this.output.push(255, value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff);
       }
+    }
+
+    this.output.push(...command);
 
-      return false;
+    if (keepStack) {
+      this.stack.splice(start, howManyArgs);
+    } else {
+      this.stack.length = 0;
     }
 
+    return false;
   }
 
-  return Type1CharString;
-}();
+}
 
-const Type1Parser = function Type1ParserClosure() {
-  const EEXEC_ENCRYPT_KEY = 55665;
-  const CHAR_STRS_ENCRYPT_KEY = 4330;
-
-  function isHexDigit(code) {
-    return code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102;
-  }
+const EEXEC_ENCRYPT_KEY = 55665;
+const CHAR_STRS_ENCRYPT_KEY = 4330;
 
-  function decrypt(data, key, discardNumber) {
-    if (discardNumber >= data.length) {
-      return new Uint8Array(0);
-    }
+function isHexDigit(code) {
+  return code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102;
+}
 
-    const c1 = 52845,
-          c2 = 22719;
-    let r = key | 0,
-        i,
-        j;
+function decrypt(data, key, discardNumber) {
+  if (discardNumber >= data.length) {
+    return new Uint8Array(0);
+  }
 
-    for (i = 0; i < discardNumber; i++) {
-      r = (data[i] + r) * c1 + c2 & (1 << 16) - 1;
-    }
+  const c1 = 52845,
+        c2 = 22719;
+  let r = key | 0,
+      i,
+      j;
 
-    const count = data.length - discardNumber;
-    const decrypted = new Uint8Array(count);
+  for (i = 0; i < discardNumber; i++) {
+    r = (data[i] + r) * c1 + c2 & (1 << 16) - 1;
+  }
 
-    for (i = discardNumber, j = 0; j < count; i++, j++) {
-      const value = data[i];
-      decrypted[j] = value ^ r >> 8;
-      r = (value + r) * c1 + c2 & (1 << 16) - 1;
-    }
+  const count = data.length - discardNumber;
+  const decrypted = new Uint8Array(count);
 
-    return decrypted;
+  for (i = discardNumber, j = 0; j < count; i++, j++) {
+    const value = data[i];
+    decrypted[j] = value ^ r >> 8;
+    r = (value + r) * c1 + c2 & (1 << 16) - 1;
   }
 
-  function decryptAscii(data, key, discardNumber) {
-    const c1 = 52845,
-          c2 = 22719;
-    let r = key | 0;
-    const count = data.length,
-          maybeLength = count >>> 1;
-    const decrypted = new Uint8Array(maybeLength);
-    let i, j;
+  return decrypted;
+}
 
-    for (i = 0, j = 0; i < count; i++) {
-      const digit1 = data[i];
+function decryptAscii(data, key, discardNumber) {
+  const c1 = 52845,
+        c2 = 22719;
+  let r = key | 0;
+  const count = data.length,
+        maybeLength = count >>> 1;
+  const decrypted = new Uint8Array(maybeLength);
+  let i, j;
 
-      if (!isHexDigit(digit1)) {
-        continue;
-      }
+  for (i = 0, j = 0; i < count; i++) {
+    const digit1 = data[i];
 
-      i++;
-      let digit2;
+    if (!isHexDigit(digit1)) {
+      continue;
+    }
 
-      while (i < count && !isHexDigit(digit2 = data[i])) {
-        i++;
-      }
+    i++;
+    let digit2;
 
-      if (i < count) {
-        const value = parseInt(String.fromCharCode(digit1, digit2), 16);
-        decrypted[j++] = value ^ r >> 8;
-        r = (value + r) * c1 + c2 & (1 << 16) - 1;
-      }
+    while (i < count && !isHexDigit(digit2 = data[i])) {
+      i++;
     }
 
-    return decrypted.slice(discardNumber, j);
+    if (i < count) {
+      const value = parseInt(String.fromCharCode(digit1, digit2), 16);
+      decrypted[j++] = value ^ r >> 8;
+      r = (value + r) * c1 + c2 & (1 << 16) - 1;
+    }
   }
 
-  function isSpecial(c) {
-    return c === 0x2f || c === 0x5b || c === 0x5d || c === 0x7b || c === 0x7d || c === 0x28 || c === 0x29;
-  }
+  return decrypted.slice(discardNumber, j);
+}
 
-  class Type1Parser {
-    constructor(stream, encrypted, seacAnalysisEnabled) {
-      if (encrypted) {
-        const data = stream.getBytes();
-        const isBinary = !((isHexDigit(data[0]) || (0, _core_utils.isWhiteSpace)(data[0])) && isHexDigit(data[1]) && isHexDigit(data[2]) && isHexDigit(data[3]) && isHexDigit(data[4]) && isHexDigit(data[5]) && isHexDigit(data[6]) && isHexDigit(data[7]));
-        stream = new _stream.Stream(isBinary ? decrypt(data, EEXEC_ENCRYPT_KEY, 4) : decryptAscii(data, EEXEC_ENCRYPT_KEY, 4));
-      }
+function isSpecial(c) {
+  return c === 0x2f || c === 0x5b || c === 0x5d || c === 0x7b || c === 0x7d || c === 0x28 || c === 0x29;
+}
 
-      this.seacAnalysisEnabled = !!seacAnalysisEnabled;
-      this.stream = stream;
-      this.nextChar();
+class Type1Parser {
+  constructor(stream, encrypted, seacAnalysisEnabled) {
+    if (encrypted) {
+      const data = stream.getBytes();
+      const isBinary = !((isHexDigit(data[0]) || (0, _core_utils.isWhiteSpace)(data[0])) && isHexDigit(data[1]) && isHexDigit(data[2]) && isHexDigit(data[3]) && isHexDigit(data[4]) && isHexDigit(data[5]) && isHexDigit(data[6]) && isHexDigit(data[7]));
+      stream = new _stream.Stream(isBinary ? decrypt(data, EEXEC_ENCRYPT_KEY, 4) : decryptAscii(data, EEXEC_ENCRYPT_KEY, 4));
     }
 
-    readNumberArray() {
-      this.getToken();
-      const array = [];
+    this.seacAnalysisEnabled = !!seacAnalysisEnabled;
+    this.stream = stream;
+    this.nextChar();
+  }
 
-      while (true) {
-        const token = this.getToken();
+  readNumberArray() {
+    this.getToken();
+    const array = [];
 
-        if (token === null || token === "]" || token === "}") {
-          break;
-        }
+    while (true) {
+      const token = this.getToken();
 
-        array.push(parseFloat(token || 0));
+      if (token === null || token === "]" || token === "}") {
+        break;
       }
 
-      return array;
-    }
-
-    readNumber() {
-      const token = this.getToken();
-      return parseFloat(token || 0);
+      array.push(parseFloat(token || 0));
     }
 
-    readInt() {
-      const token = this.getToken();
-      return parseInt(token || 0, 10) | 0;
-    }
+    return array;
+  }
 
-    readBoolean() {
-      const token = this.getToken();
-      return token === "true" ? 1 : 0;
-    }
+  readNumber() {
+    const token = this.getToken();
+    return parseFloat(token || 0);
+  }
 
-    nextChar() {
-      return this.currentChar = this.stream.getByte();
-    }
+  readInt() {
+    const token = this.getToken();
+    return parseInt(token || 0, 10) | 0;
+  }
 
-    prevChar() {
-      this.stream.skip(-2);
-      return this.currentChar = this.stream.getByte();
-    }
+  readBoolean() {
+    const token = this.getToken();
+    return token === "true" ? 1 : 0;
+  }
 
-    getToken() {
-      let comment = false;
-      let ch = this.currentChar;
+  nextChar() {
+    return this.currentChar = this.stream.getByte();
+  }
 
-      while (true) {
-        if (ch === -1) {
-          return null;
-        }
+  prevChar() {
+    this.stream.skip(-2);
+    return this.currentChar = this.stream.getByte();
+  }
 
-        if (comment) {
-          if (ch === 0x0a || ch === 0x0d) {
-            comment = false;
-          }
-        } else if (ch === 0x25) {
-          comment = true;
-        } else if (!(0, _core_utils.isWhiteSpace)(ch)) {
-          break;
-        }
+  getToken() {
+    let comment = false;
+    let ch = this.currentChar;
 
-        ch = this.nextChar();
+    while (true) {
+      if (ch === -1) {
+        return null;
       }
 
-      if (isSpecial(ch)) {
-        this.nextChar();
-        return String.fromCharCode(ch);
+      if (comment) {
+        if (ch === 0x0a || ch === 0x0d) {
+          comment = false;
+        }
+      } else if (ch === 0x25) {
+        comment = true;
+      } else if (!(0, _core_utils.isWhiteSpace)(ch)) {
+        break;
       }
 
-      let token = "";
-
-      do {
-        token += String.fromCharCode(ch);
-        ch = this.nextChar();
-      } while (ch >= 0 && !(0, _core_utils.isWhiteSpace)(ch) && !isSpecial(ch));
-
-      return token;
+      ch = this.nextChar();
     }
 
-    readCharStrings(bytes, lenIV) {
-      if (lenIV === -1) {
-        return bytes;
-      }
-
-      return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV);
+    if (isSpecial(ch)) {
+      this.nextChar();
+      return String.fromCharCode(ch);
     }
 
-    extractFontProgram(properties) {
-      const stream = this.stream;
-      const subrs = [],
-            charstrings = [];
-      const privateData = Object.create(null);
-      privateData.lenIV = 4;
-      const program = {
-        subrs: [],
-        charstrings: [],
-        properties: {
-          privateData
-        }
-      };
-      let token, length, data, lenIV;
+    let token = "";
 
-      while ((token = this.getToken()) !== null) {
-        if (token !== "/") {
-          continue;
-        }
+    do {
+      token += String.fromCharCode(ch);
+      ch = this.nextChar();
+    } while (ch >= 0 && !(0, _core_utils.isWhiteSpace)(ch) && !isSpecial(ch));
 
-        token = this.getToken();
+    return token;
+  }
 
-        switch (token) {
-          case "CharStrings":
-            this.getToken();
-            this.getToken();
-            this.getToken();
-            this.getToken();
+  readCharStrings(bytes, lenIV) {
+    if (lenIV === -1) {
+      return bytes;
+    }
 
-            while (true) {
-              token = this.getToken();
+    return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV);
+  }
 
-              if (token === null || token === "end") {
-                break;
-              }
+  extractFontProgram(properties) {
+    const stream = this.stream;
+    const subrs = [],
+          charstrings = [];
+    const privateData = Object.create(null);
+    privateData.lenIV = 4;
+    const program = {
+      subrs: [],
+      charstrings: [],
+      properties: {
+        privateData
+      }
+    };
+    let token, length, data, lenIV;
 
-              if (token !== "/") {
-                continue;
-              }
+    while ((token = this.getToken()) !== null) {
+      if (token !== "/") {
+        continue;
+      }
 
-              const glyph = this.getToken();
-              length = this.readInt();
-              this.getToken();
-              data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
-              lenIV = program.properties.privateData.lenIV;
-              const encoded = this.readCharStrings(data, lenIV);
-              this.nextChar();
-              token = this.getToken();
+      token = this.getToken();
 
-              if (token === "noaccess") {
-                this.getToken();
-              } else if (token === "/") {
-                this.prevChar();
-              }
+      switch (token) {
+        case "CharStrings":
+          this.getToken();
+          this.getToken();
+          this.getToken();
+          this.getToken();
+
+          while (true) {
+            token = this.getToken();
 
-              charstrings.push({
-                glyph,
-                encoded
-              });
+            if (token === null || token === "end") {
+              break;
             }
 
-            break;
+            if (token !== "/") {
+              continue;
+            }
 
-          case "Subrs":
-            this.readInt();
+            const glyph = this.getToken();
+            length = this.readInt();
             this.getToken();
+            data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
+            lenIV = program.properties.privateData.lenIV;
+            const encoded = this.readCharStrings(data, lenIV);
+            this.nextChar();
+            token = this.getToken();
 
-            while (this.getToken() === "dup") {
-              const index = this.readInt();
-              length = this.readInt();
+            if (token === "noaccess") {
               this.getToken();
-              data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
-              lenIV = program.properties.privateData.lenIV;
-              const encoded = this.readCharStrings(data, lenIV);
-              this.nextChar();
-              token = this.getToken();
+            } else if (token === "/") {
+              this.prevChar();
+            }
 
-              if (token === "noaccess") {
-                this.getToken();
-              }
+            charstrings.push({
+              glyph,
+              encoded
+            });
+          }
 
-              subrs[index] = encoded;
-            }
+          break;
 
-            break;
+        case "Subrs":
+          this.readInt();
+          this.getToken();
 
-          case "BlueValues":
-          case "OtherBlues":
-          case "FamilyBlues":
-          case "FamilyOtherBlues":
-            const blueArray = this.readNumberArray();
+          while (this.getToken() === "dup") {
+            const index = this.readInt();
+            length = this.readInt();
+            this.getToken();
+            data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
+            lenIV = program.properties.privateData.lenIV;
+            const encoded = this.readCharStrings(data, lenIV);
+            this.nextChar();
+            token = this.getToken();
 
-            if (blueArray.length > 0 && blueArray.length % 2 === 0 && HINTING_ENABLED) {
-              program.properties.privateData[token] = blueArray;
+            if (token === "noaccess") {
+              this.getToken();
             }
 
-            break;
+            subrs[index] = encoded;
+          }
 
-          case "StemSnapH":
-          case "StemSnapV":
-            program.properties.privateData[token] = this.readNumberArray();
-            break;
+          break;
 
-          case "StdHW":
-          case "StdVW":
-            program.properties.privateData[token] = this.readNumberArray()[0];
-            break;
+        case "BlueValues":
+        case "OtherBlues":
+        case "FamilyBlues":
+        case "FamilyOtherBlues":
+          const blueArray = this.readNumberArray();
 
-          case "BlueShift":
-          case "lenIV":
-          case "BlueFuzz":
-          case "BlueScale":
-          case "LanguageGroup":
-          case "ExpansionFactor":
-            program.properties.privateData[token] = this.readNumber();
-            break;
+          if (blueArray.length > 0 && blueArray.length % 2 === 0 && HINTING_ENABLED) {
+            program.properties.privateData[token] = blueArray;
+          }
 
-          case "ForceBold":
-            program.properties.privateData[token] = this.readBoolean();
-            break;
-        }
+          break;
+
+        case "StemSnapH":
+        case "StemSnapV":
+          program.properties.privateData[token] = this.readNumberArray();
+          break;
+
+        case "StdHW":
+        case "StdVW":
+          program.properties.privateData[token] = this.readNumberArray()[0];
+          break;
+
+        case "BlueShift":
+        case "lenIV":
+        case "BlueFuzz":
+        case "BlueScale":
+        case "LanguageGroup":
+        case "ExpansionFactor":
+          program.properties.privateData[token] = this.readNumber();
+          break;
+
+        case "ForceBold":
+          program.properties.privateData[token] = this.readBoolean();
+          break;
       }
+    }
 
-      for (const {
-        encoded,
-        glyph
-      } of charstrings) {
-        const charString = new Type1CharString();
-        const error = charString.convert(encoded, subrs, this.seacAnalysisEnabled);
-        let output = charString.output;
+    for (const {
+      encoded,
+      glyph
+    } of charstrings) {
+      const charString = new Type1CharString();
+      const error = charString.convert(encoded, subrs, this.seacAnalysisEnabled);
+      let output = charString.output;
 
-        if (error) {
-          output = [14];
-        }
+      if (error) {
+        output = [14];
+      }
 
-        const charStringObject = {
-          glyphName: glyph,
-          charstring: output,
-          width: charString.width,
-          lsb: charString.lsb,
-          seac: charString.seac
-        };
-
-        if (glyph === ".notdef") {
-          program.charstrings.unshift(charStringObject);
-        } else {
-          program.charstrings.push(charStringObject);
-        }
+      const charStringObject = {
+        glyphName: glyph,
+        charstring: output,
+        width: charString.width,
+        lsb: charString.lsb,
+        seac: charString.seac
+      };
 
-        if (properties.builtInEncoding) {
-          const index = properties.builtInEncoding.indexOf(glyph);
+      if (glyph === ".notdef") {
+        program.charstrings.unshift(charStringObject);
+      } else {
+        program.charstrings.push(charStringObject);
+      }
 
-          if (index > -1 && properties.widths[index] === undefined && index >= properties.firstChar && index <= properties.lastChar) {
-            properties.widths[index] = charString.width;
-          }
+      if (properties.builtInEncoding) {
+        const index = properties.builtInEncoding.indexOf(glyph);
+
+        if (index > -1 && properties.widths[index] === undefined && index >= properties.firstChar && index <= properties.lastChar) {
+          properties.widths[index] = charString.width;
         }
       }
-
-      return program;
     }
 
-    extractFontHeader(properties) {
-      let token;
+    return program;
+  }
 
-      while ((token = this.getToken()) !== null) {
-        if (token !== "/") {
-          continue;
-        }
+  extractFontHeader(properties) {
+    let token;
 
-        token = this.getToken();
+    while ((token = this.getToken()) !== null) {
+      if (token !== "/") {
+        continue;
+      }
 
-        switch (token) {
-          case "FontMatrix":
-            const matrix = this.readNumberArray();
-            properties.fontMatrix = matrix;
-            break;
+      token = this.getToken();
 
-          case "Encoding":
-            const encodingArg = this.getToken();
-            let encoding;
+      switch (token) {
+        case "FontMatrix":
+          const matrix = this.readNumberArray();
+          properties.fontMatrix = matrix;
+          break;
 
-            if (!/^\d+$/.test(encodingArg)) {
-              encoding = (0, _encodings.getEncoding)(encodingArg);
-            } else {
-              encoding = [];
-              const size = parseInt(encodingArg, 10) | 0;
-              this.getToken();
+        case "Encoding":
+          const encodingArg = this.getToken();
+          let encoding;
 
-              for (let j = 0; j < size; j++) {
-                token = this.getToken();
+          if (!/^\d+$/.test(encodingArg)) {
+            encoding = (0, _encodings.getEncoding)(encodingArg);
+          } else {
+            encoding = [];
+            const size = parseInt(encodingArg, 10) | 0;
+            this.getToken();
 
-                while (token !== "dup" && token !== "def") {
-                  token = this.getToken();
+            for (let j = 0; j < size; j++) {
+              token = this.getToken();
 
-                  if (token === null) {
-                    return;
-                  }
-                }
+              while (token !== "dup" && token !== "def") {
+                token = this.getToken();
 
-                if (token === "def") {
-                  break;
+                if (token === null) {
+                  return;
                 }
+              }
 
-                const index = this.readInt();
-                this.getToken();
-                const glyph = this.getToken();
-                encoding[index] = glyph;
-                this.getToken();
+              if (token === "def") {
+                break;
               }
+
+              const index = this.readInt();
+              this.getToken();
+              const glyph = this.getToken();
+              encoding[index] = glyph;
+              this.getToken();
             }
+          }
 
-            properties.builtInEncoding = encoding;
-            break;
+          properties.builtInEncoding = encoding;
+          break;
 
-          case "FontBBox":
-            const fontBBox = this.readNumberArray();
-            properties.ascent = Math.max(fontBBox[3], fontBBox[1]);
-            properties.descent = Math.min(fontBBox[1], fontBBox[3]);
-            properties.ascentScaled = true;
-            break;
-        }
+        case "FontBBox":
+          const fontBBox = this.readNumberArray();
+          properties.ascent = Math.max(fontBBox[3], fontBBox[1]);
+          properties.descent = Math.min(fontBBox[1], fontBBox[3]);
+          properties.ascentScaled = true;
+          break;
       }
     }
-
   }
 
-  return Type1Parser;
-}();
+}
 
 exports.Type1Parser = Type1Parser;

+ 9 - 2
lib/core/worker.js

@@ -99,7 +99,7 @@ class WorkerMessageHandler {
     const WorkerTasks = [];
     const verbosity = (0, _util.getVerbosityLevel)();
     const apiVersion = docParams.apiVersion;
-    const workerVersion = '2.15.349';
+    const workerVersion = '2.16.105';
 
     if (apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
@@ -447,7 +447,14 @@ class WorkerMessageHandler {
       intent
     }) {
       return pdfManager.getPage(pageIndex).then(function (page) {
-        return page.getAnnotationsData(intent);
+        const task = new WorkerTask(`GetAnnotations: page ${pageIndex}`);
+        startWorkerTask(task);
+        return page.getAnnotationsData(handler, task, intent).then(data => {
+          finishWorkerTask(task);
+          return data;
+        }, reason => {
+          finishWorkerTask(task);
+        });
       });
     });
     handler.on("GetFieldObjects", function (data) {

+ 102 - 40
lib/display/annotation_layer.js

@@ -187,6 +187,9 @@ class AnnotationElement {
       if (horizontalRadius > 0 || verticalRadius > 0) {
         const radius = `calc(${horizontalRadius}px * var(--scale-factor)) / calc(${verticalRadius}px * var(--scale-factor))`;
         container.style.borderRadius = radius;
+      } else if (this instanceof RadioButtonWidgetAnnotationElement) {
+        const radius = `calc(${width}px * var(--scale-factor)) / calc(${height}px * var(--scale-factor))`;
+        container.style.borderRadius = radius;
       }
 
       switch (data.borderStyle.style) {
@@ -363,10 +366,13 @@ class AnnotationElement {
       const action = commonActions[actionName];
 
       if (action) {
-        action({
-          detail,
+        const eventProxy = {
+          detail: {
+            [actionName]: detail
+          },
           target: element
-        });
+        };
+        action(eventProxy);
         delete storedData[actionName];
       }
     }
@@ -911,7 +917,15 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
       const storedData = storage.getValue(id, {
         value: this.data.fieldValue
       });
-      const textContent = storedData.formattedValue || storedData.value || "";
+      let textContent = storedData.formattedValue || storedData.value || "";
+      const maxLen = storage.getValue(id, {
+        charLimit: this.data.maxLen
+      }).charLimit;
+
+      if (maxLen && textContent.length > maxLen) {
+        textContent = textContent.slice(0, maxLen);
+      }
+
       const elementData = {
         userValue: textContent,
         formattedValue: null,
@@ -943,6 +957,10 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
 
       this._setRequired(element, this.data.required);
 
+      if (maxLen) {
+        element.maxLength = maxLen;
+      }
+
       element.addEventListener("input", event => {
         storage.setValue(id, {
           value: event.target.value
@@ -1002,8 +1020,46 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
 
             selRange(event) {
               event.target.setSelectionRange(...event.detail.selRange);
-            }
+            },
 
+            charLimit: event => {
+              const {
+                charLimit
+              } = event.detail;
+              const {
+                target
+              } = event;
+
+              if (charLimit === 0) {
+                target.removeAttribute("maxLength");
+                return;
+              }
+
+              target.setAttribute("maxLength", charLimit);
+              let value = elementData.userValue;
+
+              if (!value || value.length <= charLimit) {
+                return;
+              }
+
+              value = value.slice(0, charLimit);
+              target.value = elementData.userValue = value;
+              storage.setValue(id, {
+                value
+              });
+              this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
+                source: this,
+                detail: {
+                  id,
+                  name: "Keystroke",
+                  value,
+                  willCommit: true,
+                  commitKey: 1,
+                  selStart: target.selectionStart,
+                  selEnd: target.selectionEnd
+                }
+              });
+            }
           };
 
           this._dispatchEventFromSandbox(actions, jsEvent);
@@ -1146,13 +1202,9 @@ class TextWidgetAnnotationElement extends WidgetAnnotationElement {
         element.addEventListener("blur", blurListener);
       }
 
-      if (this.data.maxLen !== null) {
-        element.maxLength = this.data.maxLen;
-      }
-
       if (this.data.comb) {
         const fieldWidth = this.data.rect[2] - this.data.rect[0];
-        const combWidth = fieldWidth / this.data.maxLen;
+        const combWidth = fieldWidth / maxLen;
         element.classList.add("comb");
         element.style.letterSpacing = `calc(${combWidth}px * var(--scale-factor) - 1ch)`;
       }
@@ -1819,7 +1871,7 @@ class PopupElement {
 
     if (this.hideElement.hidden) {
       this.hideElement.hidden = false;
-      this.container.style.zIndex += 1;
+      this.container.style.zIndex = parseInt(this.container.style.zIndex) + 1000;
     }
   }
 
@@ -1830,7 +1882,7 @@ class PopupElement {
 
     if (!this.hideElement.hidden && !this.pinned) {
       this.hideElement.hidden = true;
-      this.container.style.zIndex -= 1;
+      this.container.style.zIndex = parseInt(this.container.style.zIndex) - 1000;
     }
   }
 
@@ -1843,11 +1895,26 @@ class FreeTextAnnotationElement extends AnnotationElement {
       isRenderable,
       ignoreBorder: true
     });
+    this.textContent = parameters.data.textContent;
   }
 
   render() {
     this.container.className = "freeTextAnnotation";
 
+    if (this.textContent) {
+      const content = document.createElement("div");
+      content.className = "annotationTextContent";
+      content.setAttribute("role", "comment");
+
+      for (const line of this.textContent) {
+        const lineSpan = document.createElement("span");
+        lineSpan.textContent = line;
+        content.append(lineSpan);
+      }
+
+      this.container.append(content);
+    }
+
     if (!this.data.hasPopup) {
       this._createPopup(null, this.data);
     }
@@ -2244,43 +2311,35 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
 }
 
 class AnnotationLayer {
+  static #appendElement(element, id, div, accessibilityManager) {
+    const contentElement = element.firstChild || element;
+    contentElement.id = `${_display_utils.AnnotationPrefix}${id}`;
+    div.append(element);
+    accessibilityManager?.moveElementInDOM(div, element, contentElement, false);
+  }
+
   static render(parameters) {
     const {
       annotations,
       div,
-      viewport
+      viewport,
+      accessibilityManager
     } = parameters;
     this.#setDimensions(div, viewport);
-    const sortedAnnotations = [],
-          popupAnnotations = [];
+    let zIndex = 0;
 
     for (const data of annotations) {
-      if (!data) {
-        continue;
-      }
-
-      if (data.annotationType === _util.AnnotationType.POPUP) {
-        popupAnnotations.push(data);
-        continue;
-      }
-
-      const {
-        width,
-        height
-      } = getRectDims(data.rect);
+      if (data.annotationType !== _util.AnnotationType.POPUP) {
+        const {
+          width,
+          height
+        } = getRectDims(data.rect);
 
-      if (width <= 0 || height <= 0) {
-        continue;
+        if (width <= 0 || height <= 0) {
+          continue;
+        }
       }
 
-      sortedAnnotations.push(data);
-    }
-
-    if (popupAnnotations.length) {
-      sortedAnnotations.push(...popupAnnotations);
-    }
-
-    for (const data of sortedAnnotations) {
       const element = AnnotationElementFactory.create({
         data,
         layer: div,
@@ -2309,13 +2368,16 @@ class AnnotationLayer {
 
         if (Array.isArray(rendered)) {
           for (const renderedElement of rendered) {
-            div.append(renderedElement);
+            renderedElement.style.zIndex = zIndex++;
+            AnnotationLayer.#appendElement(renderedElement, data.id, div, accessibilityManager);
           }
         } else {
+          rendered.style.zIndex = zIndex++;
+
           if (element instanceof PopupAnnotationElement) {
             div.prepend(rendered);
           } else {
-            div.append(rendered);
+            AnnotationLayer.#appendElement(rendered, data.id, div, accessibilityManager);
           }
         }
       }

+ 16 - 1
lib/display/annotation_storage.js

@@ -38,6 +38,7 @@ class AnnotationStorage {
     this._modified = false;
     this.onSetModified = null;
     this.onResetModified = null;
+    this.onAnnotationEditor = null;
   }
 
   getValue(key, defaultValue) {
@@ -54,12 +55,22 @@ class AnnotationStorage {
     return this._storage.get(key);
   }
 
-  removeKey(key) {
+  remove(key) {
     this._storage.delete(key);
 
     if (this._storage.size === 0) {
       this.resetModified();
     }
+
+    if (typeof this.onAnnotationEditor === "function") {
+      for (const value of this._storage.values()) {
+        if (value instanceof _editor.AnnotationEditor) {
+          return;
+        }
+      }
+
+      this.onAnnotationEditor(null);
+    }
   }
 
   setValue(key, value) {
@@ -83,6 +94,10 @@ class AnnotationStorage {
     if (modified) {
       this.#setModified();
     }
+
+    if (value instanceof _editor.AnnotationEditor && typeof this.onAnnotationEditor === "function") {
+      this.onAnnotationEditor(value.constructor._type);
+    }
   }
 
   has(key) {

+ 9 - 7
lib/display/api.js

@@ -98,7 +98,7 @@ function getDocument(src) {
     };
   } else {
     if (typeof src !== "object") {
-      throw new Error("Invalid parameter in getDocument, " + "need either string, URL, Uint8Array, or parameter object.");
+      throw new Error("Invalid parameter in getDocument, " + "need either string, URL, TypedArray, or parameter object.");
     }
 
     if (!src.url && !src.data && !src.range) {
@@ -151,7 +151,7 @@ function getDocument(src) {
         } else if ((0, _util.isArrayBuffer)(value)) {
           params[key] = new Uint8Array(value);
         } else {
-          throw new Error("Invalid PDF binary data: either typed array, " + "string, or array-like object is expected in the data property.");
+          throw new Error("Invalid PDF binary data: either TypedArray, " + "string, or array-like object is expected in the data property.");
         }
 
         continue;
@@ -292,7 +292,7 @@ async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
 
   const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", {
     docId,
-    apiVersion: '2.15.349',
+    apiVersion: '2.16.105',
     source: {
       data: source.data,
       url: source.url,
@@ -1305,8 +1305,10 @@ class PDFWorker {
   }
 
   _initialize() {
-    if (typeof Worker !== "undefined" && !PDFWorkerUtil.isWorkerDisabled && !PDFWorker._mainThreadWorkerMessageHandler) {
-      let workerSrc = PDFWorker.workerSrc;
+    if (!PDFWorkerUtil.isWorkerDisabled && !PDFWorker._mainThreadWorkerMessageHandler) {
+      let {
+        workerSrc
+      } = PDFWorker;
 
       try {
         if (!PDFWorkerUtil.isSameOrigin(window.location.href, workerSrc)) {
@@ -2454,7 +2456,7 @@ class InternalRenderTask {
 
 }
 
-const version = '2.15.349';
+const version = '2.16.105';
 exports.version = version;
-const build = 'b8aa9c622';
+const build = '172ccdbe5';
 exports.build = build;

+ 76 - 246
lib/display/canvas.js

@@ -26,10 +26,10 @@ Object.defineProperty(exports, "__esModule", {
 });
 exports.CanvasGraphics = void 0;
 
-var _util = require("../shared/util.js");
-
 var _display_utils = require("./display_utils.js");
 
+var _util = require("../shared/util.js");
+
 var _pattern_helper = require("./pattern_helper.js");
 
 var _image_utils = require("../shared/image_utils.js");
@@ -41,10 +41,8 @@ const MAX_FONT_SIZE = 100;
 const MAX_GROUP_SIZE = 4096;
 const EXECUTION_TIME = 15;
 const EXECUTION_STEPS = 10;
-const COMPILE_TYPE3_GLYPHS = true;
-const MAX_SIZE_TO_COMPILE = 1000;
+const MAX_SIZE_TO_COMPILE = _is_node.isNodeJS && typeof Path2D === "undefined" ? -1 : 1000;
 const FULL_CHUNK_HEIGHT = 16;
-const LINEWIDTH_SCALE_FACTOR = 1.000001;
 
 function mirrorContextOperations(ctx, destCtx) {
   if (ctx._removeMirroring) {
@@ -177,147 +175,23 @@ function mirrorContextOperations(ctx, destCtx) {
   };
 }
 
-function addContextCurrentTransform(ctx) {
-  if (ctx._transformStack) {
-    ctx._transformStack = [];
-  }
-
-  if (ctx.mozCurrentTransform) {
-    return;
-  }
-
-  ctx._originalSave = ctx.save;
-  ctx._originalRestore = ctx.restore;
-  ctx._originalRotate = ctx.rotate;
-  ctx._originalScale = ctx.scale;
-  ctx._originalTranslate = ctx.translate;
-  ctx._originalTransform = ctx.transform;
-  ctx._originalSetTransform = ctx.setTransform;
-  ctx._originalResetTransform = ctx.resetTransform;
-  ctx._transformMatrix = ctx._transformMatrix || [1, 0, 0, 1, 0, 0];
-  ctx._transformStack = [];
-
-  try {
-    const desc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(ctx), "lineWidth");
-    ctx._setLineWidth = desc.set;
-    ctx._getLineWidth = desc.get;
-    Object.defineProperty(ctx, "lineWidth", {
-      set: function setLineWidth(width) {
-        this._setLineWidth(width * LINEWIDTH_SCALE_FACTOR);
-      },
-      get: function getLineWidth() {
-        return this._getLineWidth();
-      }
-    });
-  } catch (_) {}
-
-  Object.defineProperty(ctx, "mozCurrentTransform", {
-    get: function getCurrentTransform() {
-      return this._transformMatrix;
-    }
-  });
-  Object.defineProperty(ctx, "mozCurrentTransformInverse", {
-    get: function getCurrentTransformInverse() {
-      const [a, b, c, d, e, f] = this._transformMatrix;
-      const ad_bc = a * d - b * c;
-      const bc_ad = b * c - a * d;
-      return [d / ad_bc, b / bc_ad, c / bc_ad, a / ad_bc, (d * e - c * f) / bc_ad, (b * e - a * f) / ad_bc];
-    }
-  });
-
-  ctx.save = function ctxSave() {
-    const old = this._transformMatrix;
-
-    this._transformStack.push(old);
-
-    this._transformMatrix = old.slice(0, 6);
-
-    this._originalSave();
-  };
-
-  ctx.restore = function ctxRestore() {
-    if (this._transformStack.length === 0) {
-      (0, _util.warn)("Tried to restore a ctx when the stack was already empty.");
-    }
-
-    const prev = this._transformStack.pop();
-
-    if (prev) {
-      this._transformMatrix = prev;
-
-      this._originalRestore();
-    }
-  };
-
-  ctx.translate = function ctxTranslate(x, y) {
-    const m = this._transformMatrix;
-    m[4] = m[0] * x + m[2] * y + m[4];
-    m[5] = m[1] * x + m[3] * y + m[5];
-
-    this._originalTranslate(x, y);
-  };
-
-  ctx.scale = function ctxScale(x, y) {
-    const m = this._transformMatrix;
-    m[0] *= x;
-    m[1] *= x;
-    m[2] *= y;
-    m[3] *= y;
-
-    this._originalScale(x, y);
-  };
-
-  ctx.transform = function ctxTransform(a, b, c, d, e, f) {
-    const m = this._transformMatrix;
-    this._transformMatrix = [m[0] * a + m[2] * b, m[1] * a + m[3] * b, m[0] * c + m[2] * d, m[1] * c + m[3] * d, m[0] * e + m[2] * f + m[4], m[1] * e + m[3] * f + m[5]];
-
-    ctx._originalTransform(a, b, c, d, e, f);
-  };
-
-  ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) {
-    this._transformMatrix = [a, b, c, d, e, f];
-
-    ctx._originalSetTransform(a, b, c, d, e, f);
-  };
-
-  ctx.resetTransform = function ctxResetTransform() {
-    this._transformMatrix = [1, 0, 0, 1, 0, 0];
-
-    ctx._originalResetTransform();
-  };
-
-  ctx.rotate = function ctxRotate(angle) {
-    const cosValue = Math.cos(angle);
-    const sinValue = Math.sin(angle);
-    const m = this._transformMatrix;
-    this._transformMatrix = [m[0] * cosValue + m[2] * sinValue, m[1] * cosValue + m[3] * sinValue, m[0] * -sinValue + m[2] * cosValue, m[1] * -sinValue + m[3] * cosValue, m[4], m[5]];
-
-    this._originalRotate(angle);
-  };
-}
-
 class CachedCanvases {
   constructor(canvasFactory) {
     this.canvasFactory = canvasFactory;
     this.cache = Object.create(null);
   }
 
-  getCanvas(id, width, height, trackTransform) {
+  getCanvas(id, width, height) {
     let canvasEntry;
 
     if (this.cache[id] !== undefined) {
       canvasEntry = this.cache[id];
       this.canvasFactory.reset(canvasEntry, width, height);
-      canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0);
     } else {
       canvasEntry = this.canvasFactory.create(width, height);
       this.cache[id] = canvasEntry;
     }
 
-    if (trackTransform) {
-      addContextCurrentTransform(canvasEntry.context);
-    }
-
     return canvasEntry;
   }
 
@@ -336,7 +210,7 @@ class CachedCanvases {
 }
 
 function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) {
-  const [a, b, c, d, tx, ty] = ctx.mozCurrentTransform;
+  const [a, b, c, d, tx, ty] = (0, _display_utils.getCurrentTransform)(ctx);
 
   if (b === 0 && c === 0) {
     const tlX = destX * a + tx;
@@ -380,7 +254,7 @@ function compileType3Glyph(imgData) {
     height
   } = imgData;
 
-  if (!COMPILE_TYPE3_GLYPHS || width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) {
+  if (width > MAX_SIZE_TO_COMPILE || height > MAX_SIZE_TO_COMPILE) {
     return null;
   }
 
@@ -483,13 +357,7 @@ function compileType3Glyph(imgData) {
   }
 
   const steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]);
-  let path, outlines, coords;
-
-  if (!_is_node.isNodeJS) {
-    path = new Path2D();
-  } else {
-    outlines = [];
-  }
+  const path = new Path2D();
 
   for (i = 0; count && i <= height; i++) {
     let p = i * width1;
@@ -503,12 +371,7 @@ function compileType3Glyph(imgData) {
       continue;
     }
 
-    if (path) {
-      path.moveTo(p % width1, i);
-    } else {
-      coords = [p % width1, i];
-    }
-
+    path.moveTo(p % width1, i);
     const p0 = p;
     let type = points[p];
 
@@ -529,21 +392,13 @@ function compileType3Glyph(imgData) {
         points[p] &= type >> 2 | type << 2;
       }
 
-      if (path) {
-        path.lineTo(p % width1, p / width1 | 0);
-      } else {
-        coords.push(p % width1, p / width1 | 0);
-      }
+      path.lineTo(p % width1, p / width1 | 0);
 
       if (!points[p]) {
         --count;
       }
     } while (p0 !== p);
 
-    if (!path) {
-      outlines.push(coords);
-    }
-
     --i;
   }
 
@@ -554,23 +409,7 @@ function compileType3Glyph(imgData) {
     c.save();
     c.scale(1 / width, -1 / height);
     c.translate(0, -height);
-
-    if (path) {
-      c.fill(path);
-    } else {
-      c.beginPath();
-
-      for (const o of outlines) {
-        c.moveTo(o[0], o[1]);
-
-        for (let l = 2, ll = o.length; l < ll; l += 2) {
-          c.lineTo(o[l], o[l + 1]);
-        }
-      }
-
-      c.fill();
-    }
-
+    c.fill(path);
     c.beginPath();
     c.restore();
   };
@@ -1097,11 +936,6 @@ class CanvasGraphics {
     this.outputScaleY = 1;
     this.backgroundColor = pageColors?.background || null;
     this.foregroundColor = pageColors?.foreground || null;
-
-    if (canvasCtx) {
-      addContextCurrentTransform(canvasCtx);
-    }
-
     this._cachedScaleForStroking = null;
     this._cachedGetSinglePixelWidth = null;
     this._cachedBitmapsMap = new Map();
@@ -1161,28 +995,29 @@ class CanvasGraphics {
     this.ctx.restore();
 
     if (transparency) {
-      const transparentCanvas = this.cachedCanvases.getCanvas("transparent", width, height, true);
+      const transparentCanvas = this.cachedCanvases.getCanvas("transparent", width, height);
       this.compositeCtx = this.ctx;
       this.transparentCanvas = transparentCanvas.canvas;
       this.ctx = transparentCanvas.context;
       this.ctx.save();
-      this.ctx.transform.apply(this.ctx, this.compositeCtx.mozCurrentTransform);
+      this.ctx.transform(...(0, _display_utils.getCurrentTransform)(this.compositeCtx));
     }
 
     this.ctx.save();
     resetCtxToDefault(this.ctx, this.foregroundColor);
 
     if (transform) {
-      this.ctx.transform.apply(this.ctx, transform);
+      this.ctx.transform(...transform);
       this.outputScaleX = transform[0];
       this.outputScaleY = transform[0];
     }
 
-    this.ctx.transform.apply(this.ctx, viewport.transform);
+    this.ctx.transform(...viewport.transform);
     this.viewportScale = viewport.scale;
-    this.baseTransform = this.ctx.mozCurrentTransform.slice();
+    this.baseTransform = (0, _display_utils.getCurrentTransform)(this.ctx);
 
     if (this.imageLayer) {
+      (0, _display_utils.deprecated)("The `imageLayer` functionality will be removed in the future.");
       this.imageLayer.beginLayout();
     }
   }
@@ -1305,7 +1140,7 @@ class CanvasGraphics {
         heightScale /= paintHeight / newHeight;
       }
 
-      tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight, false);
+      tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, newWidth, newHeight);
       tmpCtx = tmpCanvas.context;
       tmpCtx.clearRect(0, 0, newWidth, newHeight);
       tmpCtx.drawImage(img, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight);
@@ -1330,7 +1165,7 @@ class CanvasGraphics {
     } = img;
     const fillColor = this.current.fillColor;
     const isPatternFill = this.current.patternFill;
-    const currentTransform = ctx.mozCurrentTransform;
+    const currentTransform = (0, _display_utils.getCurrentTransform)(ctx);
     let cache, cacheKey, scaled, maskCanvas;
 
     if ((img.bitmap || img.data) && img.count > 1) {
@@ -1361,7 +1196,7 @@ class CanvasGraphics {
     }
 
     if (!scaled) {
-      maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false);
+      maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height);
       putBinaryImageMask(maskCanvas.context, img);
     }
 
@@ -1377,15 +1212,15 @@ class CanvasGraphics {
 
     const drawnWidth = Math.round(rect[2] - rect[0]) || 1;
     const drawnHeight = Math.round(rect[3] - rect[1]) || 1;
-    const fillCanvas = this.cachedCanvases.getCanvas("fillCanvas", drawnWidth, drawnHeight, true);
+    const fillCanvas = this.cachedCanvases.getCanvas("fillCanvas", drawnWidth, drawnHeight);
     const fillCtx = fillCanvas.context;
     const offsetX = Math.min(cord1[0], cord2[0]);
     const offsetY = Math.min(cord1[1], cord2[1]);
     fillCtx.translate(-offsetX, -offsetY);
-    fillCtx.transform.apply(fillCtx, maskToCanvas);
+    fillCtx.transform(...maskToCanvas);
 
     if (!scaled) {
-      scaled = this._scaleImage(maskCanvas.canvas, fillCtx.mozCurrentTransformInverse);
+      scaled = this._scaleImage(maskCanvas.canvas, (0, _display_utils.getCurrentTransformInverse)(fillCtx));
       scaled = scaled.img;
 
       if (cache && isPatternFill) {
@@ -1393,11 +1228,11 @@ class CanvasGraphics {
       }
     }
 
-    fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled(fillCtx.mozCurrentTransform, img.interpolate);
+    fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled((0, _display_utils.getCurrentTransform)(fillCtx), img.interpolate);
     drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height);
     fillCtx.globalCompositeOperation = "source-in";
 
-    const inverse = _util.Util.transform(fillCtx.mozCurrentTransformInverse, [1, 0, 0, 1, -offsetX, -offsetY]);
+    const inverse = _util.Util.transform((0, _display_utils.getCurrentTransformInverse)(fillCtx), [1, 0, 0, 1, -offsetX, -offsetY]);
 
     fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, _pattern_helper.PathType.FILL) : fillColor;
     fillCtx.fillRect(0, 0, width, height);
@@ -1534,11 +1369,11 @@ class CanvasGraphics {
     const drawnWidth = this.ctx.canvas.width;
     const drawnHeight = this.ctx.canvas.height;
     const cacheId = "smaskGroupAt" + this.groupLevel;
-    const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true);
+    const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight);
     this.suspendedCtx = this.ctx;
     this.ctx = scratchCanvas.context;
     const ctx = this.ctx;
-    ctx.setTransform.apply(ctx, this.suspendedCtx.mozCurrentTransform);
+    ctx.setTransform(...(0, _display_utils.getCurrentTransform)(this.suspendedCtx));
     copyCtxState(this.suspendedCtx, ctx);
     mirrorContextOperations(ctx, this.suspendedCtx);
     this.setGState([["BM", "source-over"], ["ca", 1], ["CA", 1]]);
@@ -1626,7 +1461,7 @@ class CanvasGraphics {
     let x = current.x,
         y = current.y;
     let startX, startY;
-    const currentTransform = ctx.mozCurrentTransform;
+    const currentTransform = (0, _display_utils.getCurrentTransform)(ctx);
     const isScalingMatrix = currentTransform[0] === 0 && currentTransform[3] === 0 || currentTransform[1] === 0 && currentTransform[2] === 0;
     const minMaxForBezier = isScalingMatrix ? minMax.slice(0) : null;
 
@@ -1734,7 +1569,7 @@ class CanvasGraphics {
     if (this.contentVisible) {
       if (typeof strokeColor === "object" && strokeColor?.getPattern) {
         ctx.save();
-        ctx.strokeStyle = strokeColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.STROKE);
+        ctx.strokeStyle = strokeColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.STROKE);
         this.rescaleAndStroke(false);
         ctx.restore();
       } else {
@@ -1763,7 +1598,7 @@ class CanvasGraphics {
 
     if (isPatternFill) {
       ctx.save();
-      ctx.fillStyle = fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL);
+      ctx.fillStyle = fillColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL);
       needRestore = true;
     }
 
@@ -1846,7 +1681,7 @@ class CanvasGraphics {
     ctx.beginPath();
 
     for (const path of paths) {
-      ctx.setTransform.apply(ctx, path.transform);
+      ctx.setTransform(...path.transform);
       ctx.translate(path.x, path.y);
       path.addToPath(ctx, path.fontSize);
     }
@@ -1975,7 +1810,7 @@ class CanvasGraphics {
       addToPath(ctx, fontSize);
 
       if (patternTransform) {
-        ctx.setTransform.apply(ctx, patternTransform);
+        ctx.setTransform(...patternTransform);
       }
 
       if (fillStrokeMode === _util.TextRenderingMode.FILL || fillStrokeMode === _util.TextRenderingMode.FILL_STROKE) {
@@ -2000,7 +1835,7 @@ class CanvasGraphics {
     if (isAddToPathSet) {
       const paths = this.pendingTextPaths || (this.pendingTextPaths = []);
       paths.push({
-        transform: ctx.mozCurrentTransform,
+        transform: (0, _display_utils.getCurrentTransform)(ctx),
         x,
         y,
         fontSize,
@@ -2012,7 +1847,7 @@ class CanvasGraphics {
   get isFontSubpixelAAEnabled() {
     const {
       context: ctx
-    } = this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled", 10, 10, false);
+    } = this.cachedCanvases.getCanvas("isFontSubpixelAAEnabled", 10, 10);
     ctx.scale(1.5, 1);
     ctx.fillText("I", 0, 10);
     const data = ctx.getImageData(0, 0, 10, 10).data;
@@ -2055,7 +1890,7 @@ class CanvasGraphics {
     const widthAdvanceScale = fontSize * current.fontMatrix[0];
     const simpleFillText = current.textRenderingMode === _util.TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill;
     ctx.save();
-    ctx.transform.apply(ctx, current.textMatrix);
+    ctx.transform(...current.textMatrix);
     ctx.translate(current.x, current.y + current.textRise);
 
     if (fontDirection > 0) {
@@ -2068,8 +1903,8 @@ class CanvasGraphics {
 
     if (current.patternFill) {
       ctx.save();
-      const pattern = current.fillColor.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL);
-      patternTransform = ctx.mozCurrentTransform;
+      const pattern = current.fillColor.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL);
+      patternTransform = (0, _display_utils.getCurrentTransform)(ctx);
       ctx.restore();
       ctx.fillStyle = pattern;
     }
@@ -2199,7 +2034,7 @@ class CanvasGraphics {
     this._cachedScaleForStroking = null;
     this._cachedGetSinglePixelWidth = null;
     ctx.save();
-    ctx.transform.apply(ctx, current.textMatrix);
+    ctx.transform(...current.textMatrix);
     ctx.translate(current.x, current.y);
     ctx.scale(textHScale, fontDirection);
 
@@ -2225,7 +2060,7 @@ class CanvasGraphics {
         this.processingType3 = glyph;
         this.save();
         ctx.scale(fontSize, fontSize);
-        ctx.transform.apply(ctx, fontMatrix);
+        ctx.transform(...fontMatrix);
         this.executeOperatorList(operatorList);
         this.restore();
       }
@@ -2254,7 +2089,7 @@ class CanvasGraphics {
 
     if (IR[0] === "TilingPattern") {
       const color = IR[1];
-      const baseTransform = this.baseTransform || this.ctx.mozCurrentTransform.slice();
+      const baseTransform = this.baseTransform || (0, _display_utils.getCurrentTransform)(this.ctx);
       const canvasGraphicsFactory = {
         createCanvasGraphics: ctx => {
           return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory);
@@ -2319,8 +2154,8 @@ class CanvasGraphics {
 
     const pattern = this._getPattern(objId);
 
-    ctx.fillStyle = pattern.getPattern(ctx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.SHADING);
-    const inv = ctx.mozCurrentTransformInverse;
+    ctx.fillStyle = pattern.getPattern(ctx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.SHADING);
+    const inv = (0, _display_utils.getCurrentTransformInverse)(ctx);
 
     if (inv) {
       const canvas = ctx.canvas;
@@ -2365,16 +2200,16 @@ class CanvasGraphics {
     this.baseTransformStack.push(this.baseTransform);
 
     if (Array.isArray(matrix) && matrix.length === 6) {
-      this.transform.apply(this, matrix);
+      this.transform(...matrix);
     }
 
-    this.baseTransform = this.ctx.mozCurrentTransform;
+    this.baseTransform = (0, _display_utils.getCurrentTransform)(this.ctx);
 
     if (bbox) {
       const width = bbox[2] - bbox[0];
       const height = bbox[3] - bbox[1];
       this.ctx.rect(bbox[0], bbox[1], width, height);
-      this.current.updateRectMinMax(this.ctx.mozCurrentTransform, bbox);
+      this.current.updateRectMinMax((0, _display_utils.getCurrentTransform)(this.ctx), bbox);
       this.clip();
       this.endPath();
     }
@@ -2411,17 +2246,17 @@ class CanvasGraphics {
       (0, _util.warn)("Knockout groups not supported.");
     }
 
-    const currentTransform = currentCtx.mozCurrentTransform;
+    const currentTransform = (0, _display_utils.getCurrentTransform)(currentCtx);
 
     if (group.matrix) {
-      currentCtx.transform.apply(currentCtx, group.matrix);
+      currentCtx.transform(...group.matrix);
     }
 
     if (!group.bbox) {
       throw new Error("Bounding box is required.");
     }
 
-    let bounds = _util.Util.getAxialAlignedBoundingBox(group.bbox, currentCtx.mozCurrentTransform);
+    let bounds = _util.Util.getAxialAlignedBoundingBox(group.bbox, (0, _display_utils.getCurrentTransform)(currentCtx));
 
     const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height];
     bounds = _util.Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0];
@@ -2449,11 +2284,11 @@ class CanvasGraphics {
       cacheId += "_smask_" + this.smaskCounter++ % 2;
     }
 
-    const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight, true);
+    const scratchCanvas = this.cachedCanvases.getCanvas(cacheId, drawnWidth, drawnHeight);
     const groupCtx = scratchCanvas.context;
     groupCtx.scale(1 / scaleX, 1 / scaleY);
     groupCtx.translate(-offsetX, -offsetY);
-    groupCtx.transform.apply(groupCtx, currentTransform);
+    groupCtx.transform(...currentTransform);
 
     if (group.smask) {
       this.smaskStack.push({
@@ -2498,10 +2333,10 @@ class CanvasGraphics {
       this.restore();
     } else {
       this.ctx.restore();
-      const currentMtx = this.ctx.mozCurrentTransform;
+      const currentMtx = (0, _display_utils.getCurrentTransform)(this.ctx);
       this.restore();
       this.ctx.save();
-      this.ctx.setTransform.apply(this.ctx, currentMtx);
+      this.ctx.setTransform(...currentMtx);
 
       const dirtyBox = _util.Util.getAxialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx);
 
@@ -2518,7 +2353,7 @@ class CanvasGraphics {
     this.save();
 
     if (this.baseTransform) {
-      this.ctx.setTransform.apply(this.ctx, this.baseTransform);
+      this.ctx.setTransform(...this.baseTransform);
     }
 
     if (Array.isArray(rect) && rect.length === 4) {
@@ -2534,7 +2369,7 @@ class CanvasGraphics {
         rect[2] = width;
         rect[3] = height;
 
-        const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale(this.ctx.mozCurrentTransform);
+        const [scaleX, scaleY] = _util.Util.singularValueDecompose2dScale((0, _display_utils.getCurrentTransform)(this.ctx));
 
         const {
           viewportScale
@@ -2549,7 +2384,6 @@ class CanvasGraphics {
         this.annotationCanvasMap.set(id, canvas);
         this.annotationCanvas.savedCtx = this.ctx;
         this.ctx = context;
-        addContextCurrentTransform(this.ctx);
         this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY);
         resetCtxToDefault(this.ctx, this.foregroundColor);
       } else {
@@ -2561,8 +2395,8 @@ class CanvasGraphics {
     }
 
     this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height);
-    this.transform.apply(this, transform);
-    this.transform.apply(this, matrix);
+    this.transform(...transform);
+    this.transform(...matrix);
   }
 
   endAnnotation() {
@@ -2613,7 +2447,7 @@ class CanvasGraphics {
     img = this.getObject(img.data, img);
     const ctx = this.ctx;
     ctx.save();
-    const currentTransform = ctx.mozCurrentTransform;
+    const currentTransform = (0, _display_utils.getCurrentTransform)(ctx);
     ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0);
 
     const mask = this._createMaskCanvas(img);
@@ -2648,17 +2482,17 @@ class CanvasGraphics {
         height,
         transform
       } = image;
-      const maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height, false);
+      const maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height);
       const maskCtx = maskCanvas.context;
       maskCtx.save();
       const img = this.getObject(data, image);
       putBinaryImageMask(maskCtx, img);
       maskCtx.globalCompositeOperation = "source-in";
-      maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, ctx.mozCurrentTransformInverse, _pattern_helper.PathType.FILL) : fillColor;
+      maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, (0, _display_utils.getCurrentTransformInverse)(ctx), _pattern_helper.PathType.FILL) : fillColor;
       maskCtx.fillRect(0, 0, width, height);
       maskCtx.restore();
       ctx.save();
-      ctx.transform.apply(ctx, transform);
+      ctx.transform(...transform);
       ctx.scale(1, -1);
       drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1);
       ctx.restore();
@@ -2726,23 +2560,24 @@ class CanvasGraphics {
     if (typeof HTMLElement === "function" && imgData instanceof HTMLElement || !imgData.data) {
       imgToPaint = imgData;
     } else {
-      const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height, false);
+      const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", width, height);
       const tmpCtx = tmpCanvas.context;
       putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);
       imgToPaint = tmpCanvas.canvas;
     }
 
-    const scaled = this._scaleImage(imgToPaint, ctx.mozCurrentTransformInverse);
+    const scaled = this._scaleImage(imgToPaint, (0, _display_utils.getCurrentTransformInverse)(ctx));
 
-    ctx.imageSmoothingEnabled = getImageSmoothingEnabled(ctx.mozCurrentTransform, imgData.interpolate);
+    ctx.imageSmoothingEnabled = getImageSmoothingEnabled((0, _display_utils.getCurrentTransform)(ctx), imgData.interpolate);
     const [rWidth, rHeight] = drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height);
 
     if (this.imageLayer) {
-      const position = this.getCanvasPosition(0, -height);
+      const [left, top] = _util.Util.applyTransform([0, -height], (0, _display_utils.getCurrentTransform)(this.ctx));
+
       this.imageLayer.appendImage({
         imgData,
-        left: position[0],
-        top: position[1],
+        left,
+        top,
         width: rWidth,
         height: rHeight
       });
@@ -2760,23 +2595,23 @@ class CanvasGraphics {
     const ctx = this.ctx;
     const w = imgData.width;
     const h = imgData.height;
-    const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h, false);
+    const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h);
     const tmpCtx = tmpCanvas.context;
     putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);
 
-    for (let i = 0, ii = map.length; i < ii; i++) {
-      const entry = map[i];
+    for (const entry of map) {
       ctx.save();
-      ctx.transform.apply(ctx, entry.transform);
+      ctx.transform(...entry.transform);
       ctx.scale(1, -1);
       drawImageAtIntegerCoords(ctx, tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1);
 
       if (this.imageLayer) {
-        const position = this.getCanvasPosition(entry.x, entry.y);
+        const [left, top] = _util.Util.applyTransform([entry.x, entry.y], (0, _display_utils.getCurrentTransform)(this.ctx));
+
         this.imageLayer.appendImage({
           imgData,
-          left: position[0],
-          top: position[1],
+          left,
+          top,
           width: w,
           height: h
         });
@@ -2861,7 +2696,7 @@ class CanvasGraphics {
 
   getSinglePixelWidth() {
     if (!this._cachedGetSinglePixelWidth) {
-      const m = this.ctx.mozCurrentTransform;
+      const m = (0, _display_utils.getCurrentTransform)(this.ctx);
 
       if (m[1] === 0 && m[2] === 0) {
         this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3]));
@@ -2881,7 +2716,7 @@ class CanvasGraphics {
       const {
         lineWidth
       } = this.current;
-      const m = this.ctx.mozCurrentTransform;
+      const m = (0, _display_utils.getCurrentTransform)(this.ctx);
       let scaleX, scaleY;
 
       if (m[1] === 0 && m[2] === 0) {
@@ -2936,7 +2771,7 @@ class CanvasGraphics {
     let savedMatrix, savedDashes, savedDashOffset;
 
     if (saveRestore) {
-      savedMatrix = ctx.mozCurrentTransform.slice();
+      savedMatrix = (0, _display_utils.getCurrentTransform)(ctx);
       savedDashes = ctx.getLineDash().slice();
       savedDashOffset = ctx.lineDashOffset;
     }
@@ -2954,11 +2789,6 @@ class CanvasGraphics {
     }
   }
 
-  getCanvasPosition(x, y) {
-    const transform = this.ctx.mozCurrentTransform;
-    return [transform[0] * x + transform[2] * y + transform[4], transform[1] * x + transform[3] * y + transform[5]];
-  }
-
   isContentVisible() {
     for (let i = this.markedContentStack.length - 1; i >= 0; i--) {
       if (!this.markedContentStack[i].visible) {

+ 26 - 25
lib/display/display_utils.js

@@ -24,10 +24,11 @@
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.StatTimer = exports.RenderingCancelledException = exports.PixelsPerInch = exports.PageViewport = exports.PDFDateString = exports.DOMStandardFontDataFactory = exports.DOMSVGFactory = exports.DOMCanvasFactory = exports.DOMCMapReaderFactory = void 0;
-exports.binarySearchFirstItem = binarySearchFirstItem;
+exports.StatTimer = exports.RenderingCancelledException = exports.PixelsPerInch = exports.PageViewport = exports.PDFDateString = exports.DOMStandardFontDataFactory = exports.DOMSVGFactory = exports.DOMCanvasFactory = exports.DOMCMapReaderFactory = exports.AnnotationPrefix = void 0;
 exports.deprecated = deprecated;
 exports.getColorValues = getColorValues;
+exports.getCurrentTransform = getCurrentTransform;
+exports.getCurrentTransformInverse = getCurrentTransformInverse;
 exports.getFilenameFromUrl = getFilenameFromUrl;
 exports.getPdfFilenameFromUrl = getPdfFilenameFromUrl;
 exports.getRGB = getRGB;
@@ -42,6 +43,8 @@ var _base_factory = require("./base_factory.js");
 var _util = require("../shared/util.js");
 
 const SVG_NS = "http://www.w3.org/2000/svg";
+const AnnotationPrefix = "pdfjs_internal_id_";
+exports.AnnotationPrefix = AnnotationPrefix;
 
 class PixelsPerInch {
   static CSS = 96.0;
@@ -512,28 +515,26 @@ function getColorValues(colors) {
   span.remove();
 }
 
-function binarySearchFirstItem(items, condition, start = 0) {
-  let minIndex = start;
-  let maxIndex = items.length - 1;
-
-  if (maxIndex < 0 || !condition(items[maxIndex])) {
-    return items.length;
-  }
-
-  if (condition(items[minIndex])) {
-    return minIndex;
-  }
-
-  while (minIndex < maxIndex) {
-    const currentIndex = minIndex + maxIndex >> 1;
-    const currentItem = items[currentIndex];
-
-    if (condition(currentItem)) {
-      maxIndex = currentIndex;
-    } else {
-      minIndex = currentIndex + 1;
-    }
-  }
+function getCurrentTransform(ctx) {
+  const {
+    a,
+    b,
+    c,
+    d,
+    e,
+    f
+  } = ctx.getTransform();
+  return [a, b, c, d, e, f];
+}
 
-  return minIndex;
+function getCurrentTransformInverse(ctx) {
+  const {
+    a,
+    b,
+    c,
+    d,
+    e,
+    f
+  } = ctx.getTransform().invertSelf();
+  return [a, b, c, d, e, f];
 }

+ 21 - 158
lib/display/editor/annotation_editor_layer.js

@@ -26,26 +26,23 @@ Object.defineProperty(exports, "__esModule", {
 });
 exports.AnnotationEditorLayer = void 0;
 
-var _util = require("../../shared/util.js");
-
 var _tools = require("./tools.js");
 
-var _display_utils = require("../display_utils.js");
+var _util = require("../../shared/util.js");
 
 var _freetext = require("./freetext.js");
 
 var _ink = require("./ink.js");
 
 class AnnotationEditorLayer {
+  #accessibilityManager;
   #allowClick = false;
   #boundPointerup = this.pointerup.bind(this);
   #boundPointerdown = this.pointerdown.bind(this);
   #editors = new Map();
+  #hadPointerDown = false;
   #isCleaningUp = false;
-  #textLayerMap = new WeakMap();
-  #textNodes = new Map();
   #uiManager;
-  #waitingEditors = new Set();
   static _initialized = false;
 
   constructor(options) {
@@ -63,38 +60,10 @@ class AnnotationEditorLayer {
     this.annotationStorage = options.annotationStorage;
     this.pageIndex = options.pageIndex;
     this.div = options.div;
+    this.#accessibilityManager = options.accessibilityManager;
     this.#uiManager.addLayer(this);
   }
 
-  get textLayerElements() {
-    const textLayer = this.div.parentNode.getElementsByClassName("textLayer").item(0);
-
-    if (!textLayer) {
-      return (0, _util.shadow)(this, "textLayerElements", null);
-    }
-
-    let textChildren = this.#textLayerMap.get(textLayer);
-
-    if (textChildren) {
-      return textChildren;
-    }
-
-    textChildren = textLayer.querySelectorAll(`span[role="presentation"]`);
-
-    if (textChildren.length === 0) {
-      return (0, _util.shadow)(this, "textLayerElements", null);
-    }
-
-    textChildren = Array.from(textChildren);
-    textChildren.sort(AnnotationEditorLayer.#compareElementPositions);
-    this.#textLayerMap.set(textLayer, textChildren);
-    return textChildren;
-  }
-
-  get #hasTextLayer() {
-    return !!this.div.parentNode.querySelector(".textLayer .endOfContent");
-  }
-
   updateToolbar(mode) {
     this.#uiManager.updateToolbar(mode);
   }
@@ -183,13 +152,13 @@ class AnnotationEditorLayer {
 
   detach(editor) {
     this.#editors.delete(editor.id);
-    this.removePointerInTextLayer(editor);
+    this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv);
   }
 
   remove(editor) {
     this.#uiManager.removeEditor(editor);
     this.detach(editor);
-    this.annotationStorage.removeKey(editor.id);
+    this.annotationStorage.remove(editor.id);
     editor.div.style.display = "none";
     setTimeout(() => {
       editor.div.style.display = "";
@@ -222,124 +191,8 @@ class AnnotationEditorLayer {
     }
   }
 
-  static #compareElementPositions(e1, e2) {
-    const rect1 = e1.getBoundingClientRect();
-    const rect2 = e2.getBoundingClientRect();
-
-    if (rect1.y + rect1.height <= rect2.y) {
-      return -1;
-    }
-
-    if (rect2.y + rect2.height <= rect1.y) {
-      return +1;
-    }
-
-    const centerX1 = rect1.x + rect1.width / 2;
-    const centerX2 = rect2.x + rect2.width / 2;
-    return centerX1 - centerX2;
-  }
-
-  onTextLayerRendered() {
-    this.#textNodes.clear();
-
-    for (const editor of this.#waitingEditors) {
-      if (editor.isAttachedToDOM) {
-        this.addPointerInTextLayer(editor);
-      }
-    }
-
-    this.#waitingEditors.clear();
-  }
-
-  removePointerInTextLayer(editor) {
-    if (!this.#hasTextLayer) {
-      this.#waitingEditors.delete(editor);
-      return;
-    }
-
-    const {
-      id
-    } = editor;
-    const node = this.#textNodes.get(id);
-
-    if (!node) {
-      return;
-    }
-
-    this.#textNodes.delete(id);
-    let owns = node.getAttribute("aria-owns");
-
-    if (owns?.includes(id)) {
-      owns = owns.split(" ").filter(x => x !== id).join(" ");
-
-      if (owns) {
-        node.setAttribute("aria-owns", owns);
-      } else {
-        node.removeAttribute("aria-owns");
-        node.setAttribute("role", "presentation");
-      }
-    }
-  }
-
-  addPointerInTextLayer(editor) {
-    if (!this.#hasTextLayer) {
-      this.#waitingEditors.add(editor);
-      return;
-    }
-
-    this.removePointerInTextLayer(editor);
-    const children = this.textLayerElements;
-
-    if (!children) {
-      return;
-    }
-
-    const {
-      contentDiv
-    } = editor;
-    const id = editor.getIdForTextLayer();
-    const index = (0, _display_utils.binarySearchFirstItem)(children, node => AnnotationEditorLayer.#compareElementPositions(contentDiv, node) < 0);
-    const node = children[Math.max(0, index - 1)];
-    const owns = node.getAttribute("aria-owns");
-
-    if (!owns?.includes(id)) {
-      node.setAttribute("aria-owns", owns ? `${owns} ${id}` : id);
-    }
-
-    node.removeAttribute("role");
-    this.#textNodes.set(id, node);
-  }
-
-  moveDivInDOM(editor) {
-    this.addPointerInTextLayer(editor);
-    const {
-      div,
-      contentDiv
-    } = editor;
-
-    if (!this.div.hasChildNodes()) {
-      this.div.append(div);
-      return;
-    }
-
-    const children = Array.from(this.div.childNodes).filter(node => node !== div);
-
-    if (children.length === 0) {
-      return;
-    }
-
-    const index = (0, _display_utils.binarySearchFirstItem)(children, node => AnnotationEditorLayer.#compareElementPositions(contentDiv, node) < 0);
-
-    if (index === 0) {
-      children[0].before(div);
-    } else {
-      children[index - 1].after(div);
-    }
-  }
-
   add(editor) {
     this.#changeParent(editor);
-    this.addToAnnotationStorage(editor);
     this.#uiManager.addEditor(editor);
     this.attach(editor);
 
@@ -349,8 +202,13 @@ class AnnotationEditorLayer {
       editor.isAttachedToDOM = true;
     }
 
-    this.moveDivInDOM(editor);
+    this.moveEditorInDOM(editor);
     editor.onceAdded();
+    this.addToAnnotationStorage(editor);
+  }
+
+  moveEditorInDOM(editor) {
+    this.#accessibilityManager?.moveElementInDOM(this.div, editor.div, editor.contentDiv, true);
   }
 
   addToAnnotationStorage(editor) {
@@ -470,6 +328,12 @@ class AnnotationEditorLayer {
       return;
     }
 
+    if (!this.#hadPointerDown) {
+      return;
+    }
+
+    this.#hadPointerDown = false;
+
     if (!this.#allowClick) {
       this.#allowClick = true;
       return;
@@ -489,6 +353,7 @@ class AnnotationEditorLayer {
       return;
     }
 
+    this.#hadPointerDown = true;
     const editor = this.#uiManager.getActive();
     this.#allowClick = !editor || editor.isEmpty();
   }
@@ -508,7 +373,7 @@ class AnnotationEditorLayer {
     const endX = event.clientX - rect.x;
     const endY = event.clientY - rect.y;
     editor.translate(endX - editor.startX, endY - editor.startY);
-    this.moveDivInDOM(editor);
+    this.moveEditorInDOM(editor);
     editor.div.focus();
   }
 
@@ -522,16 +387,14 @@ class AnnotationEditorLayer {
     }
 
     for (const editor of this.#editors.values()) {
-      this.removePointerInTextLayer(editor);
+      this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv);
       editor.isAttachedToDOM = false;
       editor.div.remove();
       editor.parent = null;
     }
 
-    this.#textNodes.clear();
     this.div = null;
     this.#editors.clear();
-    this.#waitingEditors.clear();
     this.#uiManager.removeLayer(this);
   }
 

+ 0 - 4
lib/display/editor/editor.js

@@ -321,10 +321,6 @@ class AnnotationEditor {
 
   enableEditing() {}
 
-  getIdForTextLayer() {
-    return this.id;
-  }
-
   get propertiesToUpdate() {
     return {};
   }

+ 10 - 8
lib/display/editor/freetext.js

@@ -38,7 +38,6 @@ class FreeTextEditor extends _editor.AnnotationEditor {
   #boundEditorDivKeydown = this.editorDivKeydown.bind(this);
   #color;
   #content = "";
-  #contentHTML = "";
   #hasAlreadyBeenCommitted = false;
   #fontSize;
   static _freeTextDefaultContent = "";
@@ -47,6 +46,7 @@ class FreeTextEditor extends _editor.AnnotationEditor {
   static _defaultColor = null;
   static _defaultFontSize = 10;
   static _keyboardManager = new _tools.KeyboardManager([[["ctrl+Enter", "mac+meta+Enter", "Escape", "mac+Escape"], FreeTextEditor.prototype.commitOrRemove]]);
+  static _type = "freetext";
 
   constructor(params) {
     super({ ...params,
@@ -159,6 +159,7 @@ class FreeTextEditor extends _editor.AnnotationEditor {
     this.parent.setEditingState(false);
     this.parent.updateToolbar(_util.AnnotationEditorType.FREETEXT);
     super.enableEditMode();
+    this.enableEditing();
     this.overlayDiv.classList.remove("enabled");
     this.editorDiv.contentEditable = true;
     this.div.draggable = false;
@@ -174,6 +175,7 @@ class FreeTextEditor extends _editor.AnnotationEditor {
 
     this.parent.setEditingState(true);
     super.disableEditMode();
+    this.disableEditing();
     this.overlayDiv.classList.add("enabled");
     this.editorDiv.contentEditable = false;
     this.div.draggable = true;
@@ -250,7 +252,6 @@ class FreeTextEditor extends _editor.AnnotationEditor {
     }
 
     this.disableEditMode();
-    this.#contentHTML = this.editorDiv.innerHTML;
     this.#content = this.#extractText().trimEnd();
     this.#setEditorDimensions();
   }
@@ -293,10 +294,6 @@ class FreeTextEditor extends _editor.AnnotationEditor {
     this.editorDiv.setAttribute("aria-multiline", true);
   }
 
-  getIdForTextLayer() {
-    return this.editorDiv.id;
-  }
-
   render() {
     if (this.div) {
       return this.div;
@@ -334,7 +331,13 @@ class FreeTextEditor extends _editor.AnnotationEditor {
     if (this.width) {
       const [parentWidth, parentHeight] = this.parent.viewportBaseDimensions;
       this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight);
-      this.editorDiv.innerHTML = this.#contentHTML;
+
+      for (const line of this.#content.split("\n")) {
+        const div = document.createElement("div");
+        div.append(line ? document.createTextNode(line) : document.createElement("br"));
+        this.editorDiv.append(div);
+      }
+
       this.div.draggable = true;
       this.editorDiv.contentEditable = false;
     } else {
@@ -354,7 +357,6 @@ class FreeTextEditor extends _editor.AnnotationEditor {
     editor.#fontSize = data.fontSize;
     editor.#color = _util.Util.makeHexColor(...data.color);
     editor.#content = data.value;
-    editor.#contentHTML = data.value.split("\n").map(line => `<div>${line}</div>`).join("");
     return editor;
   }
 

+ 4 - 3
lib/display/editor/ink.js

@@ -61,6 +61,7 @@ class InkEditor extends _editor.AnnotationEditor {
   static _defaultOpacity = 1;
   static _defaultThickness = 1;
   static _l10nPromise;
+  static _type = "ink";
 
   constructor(params) {
     super({ ...params,
@@ -412,7 +413,7 @@ class InkEditor extends _editor.AnnotationEditor {
     this.div.classList.add("disabled");
     this.#fitToContent(true);
     this.parent.addInkEditorIfNeeded(true);
-    this.parent.moveDivInDOM(this);
+    this.parent.moveEditorInDOM(this);
     this.div.focus();
   }
 
@@ -784,8 +785,8 @@ class InkEditor extends _editor.AnnotationEditor {
     }
 
     const bbox = editor.#getBbox();
-    editor.#baseWidth = bbox[2] - bbox[0];
-    editor.#baseHeight = bbox[3] - bbox[1];
+    editor.#baseWidth = Math.max(RESIZER_SIZE, bbox[2] - bbox[0]);
+    editor.#baseHeight = Math.max(RESIZER_SIZE, bbox[3] - bbox[1]);
     editor.#setScaleFactor(width, height);
     return editor;
   }

+ 0 - 13
lib/display/editor/tools.js

@@ -320,7 +320,6 @@ class AnnotationEditorUIManager {
   #boundKeydown = this.keydown.bind(this);
   #boundOnEditingAction = this.onEditingAction.bind(this);
   #boundOnPageChanging = this.onPageChanging.bind(this);
-  #boundOnTextLayerRendered = this.onTextLayerRendered.bind(this);
   #previousStates = {
     isEditing: false,
     isEmpty: true,
@@ -339,8 +338,6 @@ class AnnotationEditorUIManager {
     this.#eventBus._on("editingaction", this.#boundOnEditingAction);
 
     this.#eventBus._on("pagechanging", this.#boundOnPageChanging);
-
-    this.#eventBus._on("textlayerrendered", this.#boundOnTextLayerRendered);
   }
 
   destroy() {
@@ -350,8 +347,6 @@ class AnnotationEditorUIManager {
 
     this.#eventBus._off("pagechanging", this.#boundOnPageChanging);
 
-    this.#eventBus._off("textlayerrendered", this.#boundOnTextLayerRendered);
-
     for (const layer of this.#allLayers.values()) {
       layer.destroy();
     }
@@ -370,14 +365,6 @@ class AnnotationEditorUIManager {
     this.#currentPageIndex = pageNumber - 1;
   }
 
-  onTextLayerRendered({
-    pageNumber
-  }) {
-    const pageIndex = pageNumber - 1;
-    const layer = this.#allLayers.get(pageIndex);
-    layer?.onTextLayerRendered();
-  }
-
   focusMainContainer() {
     this.#container.focus();
   }

+ 5 - 16
lib/display/fetch_stream.js

@@ -36,7 +36,7 @@ function createFetchOptions(headers, withCredentials, abortController) {
   return {
     method: "GET",
     headers,
-    signal: abortController?.signal,
+    signal: abortController.signal,
     mode: "cors",
     credentials: withCredentials ? "include" : "same-origin",
     redirect: "follow"
@@ -121,10 +121,7 @@ class PDFFetchStreamReader {
       this._disableRange = true;
     }
 
-    if (typeof AbortController !== "undefined") {
-      this._abortController = new AbortController();
-    }
-
+    this._abortController = new AbortController();
     this._isStreamingSupported = !source.disableStream;
     this._isRangeSupported = !source.disableRange;
     this._headers = createHeaders(this._stream.httpHeaders);
@@ -217,9 +214,7 @@ class PDFFetchStreamReader {
       this._reader.cancel(reason);
     }
 
-    if (this._abortController) {
-      this._abortController.abort();
-    }
+    this._abortController.abort();
   }
 
 }
@@ -233,11 +228,7 @@ class PDFFetchStreamRangeReader {
     this._withCredentials = source.withCredentials || false;
     this._readCapability = (0, _util.createPromiseCapability)();
     this._isStreamingSupported = !source.disableStream;
-
-    if (typeof AbortController !== "undefined") {
-      this._abortController = new AbortController();
-    }
-
+    this._abortController = new AbortController();
     this._headers = createHeaders(this._stream.httpHeaders);
 
     this._headers.append("Range", `bytes=${begin}-${end - 1}`);
@@ -293,9 +284,7 @@ class PDFFetchStreamRangeReader {
       this._reader.cancel(reason);
     }
 
-    if (this._abortController) {
-      this._abortController.abort();
-    }
+    this._abortController.abort();
   }
 
 }

+ 10 - 8
lib/display/pattern_helper.js

@@ -29,6 +29,8 @@ exports.getShadingPattern = getShadingPattern;
 
 var _util = require("../shared/util.js");
 
+var _display_utils = require("./display_utils.js");
+
 var _is_node = require("../shared/is_node.js");
 
 const PathType = {
@@ -96,7 +98,7 @@ class RadialAxialShadingPattern extends BaseShadingPattern {
     let pattern;
 
     if (pathType === PathType.STROKE || pathType === PathType.FILL) {
-      const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, ctx.mozCurrentTransform) || [0, 0, 0, 0];
+      const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, (0, _display_utils.getCurrentTransform)(ctx)) || [0, 0, 0, 0];
       const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1;
       const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1;
       const tmpCanvas = owner.cachedCanvases.getCanvas("pattern", width, height, true);
@@ -106,10 +108,10 @@ class RadialAxialShadingPattern extends BaseShadingPattern {
       tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height);
       tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]);
       inverse = _util.Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]);
-      tmpCtx.transform.apply(tmpCtx, owner.baseTransform);
+      tmpCtx.transform(...owner.baseTransform);
 
       if (this.matrix) {
-        tmpCtx.transform.apply(tmpCtx, this.matrix);
+        tmpCtx.transform(...this.matrix);
       }
 
       applyBoundingBox(tmpCtx, this._bbox);
@@ -361,7 +363,7 @@ class MeshShadingPattern extends BaseShadingPattern {
     let scale;
 
     if (pathType === PathType.SHADING) {
-      scale = _util.Util.singularValueDecompose2dScale(ctx.mozCurrentTransform);
+      scale = _util.Util.singularValueDecompose2dScale((0, _display_utils.getCurrentTransform)(ctx));
     } else {
       scale = _util.Util.singularValueDecompose2dScale(owner.baseTransform);
 
@@ -375,10 +377,10 @@ class MeshShadingPattern extends BaseShadingPattern {
     const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.cachedCanvases);
 
     if (pathType !== PathType.SHADING) {
-      ctx.setTransform.apply(ctx, owner.baseTransform);
+      ctx.setTransform(...owner.baseTransform);
 
       if (this.matrix) {
-        ctx.transform.apply(ctx, this.matrix);
+        ctx.transform(...this.matrix);
       }
     }
 
@@ -481,7 +483,7 @@ class TilingPattern {
     graphics.transform(dimx.scale, 0, 0, dimy.scale, 0, 0);
     tmpCtx.save();
     this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1);
-    graphics.baseTransform = graphics.ctx.mozCurrentTransform.slice();
+    graphics.baseTransform = (0, _display_utils.getCurrentTransform)(graphics.ctx);
     graphics.executeOperatorList(operatorList);
     graphics.endDrawing();
     return {
@@ -514,7 +516,7 @@ class TilingPattern {
     const bboxWidth = x1 - x0;
     const bboxHeight = y1 - y0;
     graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight);
-    graphics.current.updateRectMinMax(graphics.ctx.mozCurrentTransform, [x0, y0, x1, y1]);
+    graphics.current.updateRectMinMax((0, _display_utils.getCurrentTransform)(graphics.ctx), [x0, y0, x1, y1]);
     graphics.clip();
     graphics.endPath();
   }

+ 4 - 10
lib/pdf.js

@@ -174,12 +174,6 @@ Object.defineProperty(exports, "XfaLayer", {
     return _xfa_layer.XfaLayer;
   }
 });
-Object.defineProperty(exports, "binarySearchFirstItem", {
-  enumerable: true,
-  get: function () {
-    return _display_utils.binarySearchFirstItem;
-  }
-});
 Object.defineProperty(exports, "build", {
   enumerable: true,
   get: function () {
@@ -255,10 +249,10 @@ Object.defineProperty(exports, "version", {
 
 var _util = require("./shared/util.js");
 
-var _display_utils = require("./display/display_utils.js");
-
 var _api = require("./display/api.js");
 
+var _display_utils = require("./display/display_utils.js");
+
 var _annotation_editor_layer = require("./display/editor/annotation_editor_layer.js");
 
 var _tools = require("./display/editor/tools.js");
@@ -275,8 +269,8 @@ var _svg = require("./display/svg.js");
 
 var _xfa_layer = require("./display/xfa_layer.js");
 
-const pdfjsVersion = '2.15.349';
-const pdfjsBuild = 'b8aa9c622';
+const pdfjsVersion = '2.16.105';
+const pdfjsBuild = '172ccdbe5';
 {
   if (_is_node.isNodeJS) {
     const {

文件差異過大導致無法顯示
+ 2 - 2
lib/pdf.sandbox.js


+ 2 - 2
lib/pdf.worker.js

@@ -33,5 +33,5 @@ Object.defineProperty(exports, "WorkerMessageHandler", {
 
 var _worker = require("./core/worker.js");
 
-const pdfjsVersion = '2.15.349';
-const pdfjsBuild = 'b8aa9c622';
+const pdfjsVersion = '2.16.105';
+const pdfjsBuild = '172ccdbe5';

+ 16 - 2
lib/test/unit/annotation_spec.js

@@ -1295,7 +1295,7 @@ describe("annotation", function () {
       } = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
       expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
       expect(data.textAlignment).toEqual(null);
-      expect(data.maxLen).toEqual(null);
+      expect(data.maxLen).toEqual(0);
       expect(data.readOnly).toEqual(false);
       expect(data.hidden).toEqual(false);
       expect(data.multiLine).toEqual(false);
@@ -1318,7 +1318,7 @@ describe("annotation", function () {
       } = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
       expect(data.annotationType).toEqual(_util.AnnotationType.WIDGET);
       expect(data.textAlignment).toEqual(null);
-      expect(data.maxLen).toEqual(null);
+      expect(data.maxLen).toEqual(0);
       expect(data.readOnly).toEqual(false);
       expect(data.hidden).toEqual(false);
       expect(data.multiLine).toEqual(false);
@@ -3067,6 +3067,20 @@ describe("annotation", function () {
       expect(opList.fnArray.length).toEqual(16);
       expect(opList.fnArray).toEqual([_util.OPS.beginAnnotation, _util.OPS.save, _util.OPS.constructPath, _util.OPS.clip, _util.OPS.endPath, _util.OPS.beginText, _util.OPS.setTextMatrix, _util.OPS.setCharSpacing, _util.OPS.setFillRGBColor, _util.OPS.dependency, _util.OPS.setFont, _util.OPS.moveText, _util.OPS.showText, _util.OPS.endText, _util.OPS.restore, _util.OPS.endAnnotation]);
     });
+    it("should extract the text from a FreeText annotation", async function () {
+      partialEvaluator.xref = new _test_utils.XRefMock();
+      const task = new _worker.WorkerTask("test FreeText text extraction");
+      const freetextAnnotation = (await _annotation.AnnotationFactory.printNewAnnotations(partialEvaluator, task, [{
+        annotationType: _util.AnnotationEditorType.FREETEXT,
+        rect: [12, 34, 56, 78],
+        rotation: 0,
+        fontSize: 10,
+        color: [0, 0, 0],
+        value: "Hello PDF.js\nWorld !"
+      }]))[0];
+      await freetextAnnotation.extractTextContent(partialEvaluator, task, [-Infinity, -Infinity, Infinity, Infinity]);
+      expect(freetextAnnotation.data.textContent).toEqual(["Hello PDF.js", "World !"]);
+    });
   });
   describe("InkAnnotation", function () {
     it("should handle a single ink list", async function () {

+ 25 - 3
lib/test/unit/api_spec.js

@@ -130,10 +130,11 @@ describe("api", function () {
       await destroyed;
       expect(true).toEqual(true);
     });
-    it("creates pdf doc from typed array", async function () {
+    it("creates pdf doc from TypedArray", async function () {
       const typedArrayPdf = await _test_utils.DefaultFileReaderFactory.fetch({
         path: _test_utils.TEST_PDFS_PATH + basicApiFileName
       });
+      expect(typedArrayPdf instanceof Uint8Array).toEqual(true);
       expect(typedArrayPdf.length).toEqual(basicApiFileLength);
       const loadingTask = (0, _api.getDocument)(typedArrayPdf);
       expect(loadingTask instanceof _api.PDFDocumentLoadingTask).toEqual(true);
@@ -148,6 +149,27 @@ describe("api", function () {
       expect(data[1].loaded / data[1].total).toEqual(1);
       await loadingTask.destroy();
     });
+    it("creates pdf doc from ArrayBuffer", async function () {
+      const {
+        buffer: arrayBufferPdf
+      } = await _test_utils.DefaultFileReaderFactory.fetch({
+        path: _test_utils.TEST_PDFS_PATH + basicApiFileName
+      });
+      expect(arrayBufferPdf instanceof ArrayBuffer).toEqual(true);
+      expect(arrayBufferPdf.byteLength).toEqual(basicApiFileLength);
+      const loadingTask = (0, _api.getDocument)(arrayBufferPdf);
+      expect(loadingTask instanceof _api.PDFDocumentLoadingTask).toEqual(true);
+      const progressReportedCapability = (0, _util.createPromiseCapability)();
+
+      loadingTask.onProgress = function (data) {
+        progressReportedCapability.resolve(data);
+      };
+
+      const data = await Promise.all([loadingTask.promise, progressReportedCapability.promise]);
+      expect(data[0] instanceof _api.PDFDocumentProxy).toEqual(true);
+      expect(data[1].loaded / data[1].total).toEqual(1);
+      await loadingTask.destroy();
+    });
     it("creates pdf doc from invalid PDF file", async function () {
       const loadingTask = (0, _api.getDocument)((0, _test_utils.buildGetDocumentParams)("bug1020226.pdf"));
       expect(loadingTask instanceof _api.PDFDocumentLoadingTask).toEqual(true);
@@ -305,7 +327,7 @@ describe("api", function () {
       });
       await loadingTask.destroy();
     });
-    it("creates pdf doc from empty typed array", async function () {
+    it("creates pdf doc from empty TypedArray", async function () {
       const loadingTask = (0, _api.getDocument)(new Uint8Array(0));
       expect(loadingTask instanceof _api.PDFDocumentLoadingTask).toEqual(true);
 
@@ -990,7 +1012,7 @@ describe("api", function () {
           defaultValue: "",
           multiline: false,
           password: false,
-          charLimit: null,
+          charLimit: 0,
           comb: false,
           editable: true,
           hidden: false,

+ 0 - 33
lib/test/unit/display_utils_spec.js

@@ -28,39 +28,6 @@ var _util = require("../../shared/util.js");
 var _is_node = require("../../shared/is_node.js");
 
 describe("display_utils", function () {
-  describe("binary search", function () {
-    function isTrue(boolean) {
-      return boolean;
-    }
-
-    function isGreater3(number) {
-      return number > 3;
-    }
-
-    it("empty array", function () {
-      expect((0, _display_utils.binarySearchFirstItem)([], isTrue)).toEqual(0);
-    });
-    it("single boolean entry", function () {
-      expect((0, _display_utils.binarySearchFirstItem)([false], isTrue)).toEqual(1);
-      expect((0, _display_utils.binarySearchFirstItem)([true], isTrue)).toEqual(0);
-    });
-    it("three boolean entries", function () {
-      expect((0, _display_utils.binarySearchFirstItem)([true, true, true], isTrue)).toEqual(0);
-      expect((0, _display_utils.binarySearchFirstItem)([false, true, true], isTrue)).toEqual(1);
-      expect((0, _display_utils.binarySearchFirstItem)([false, false, true], isTrue)).toEqual(2);
-      expect((0, _display_utils.binarySearchFirstItem)([false, false, false], isTrue)).toEqual(3);
-    });
-    it("three numeric entries", function () {
-      expect((0, _display_utils.binarySearchFirstItem)([0, 1, 2], isGreater3)).toEqual(3);
-      expect((0, _display_utils.binarySearchFirstItem)([2, 3, 4], isGreater3)).toEqual(2);
-      expect((0, _display_utils.binarySearchFirstItem)([4, 5, 6], isGreater3)).toEqual(0);
-    });
-    it("three numeric entries and a start index", function () {
-      expect((0, _display_utils.binarySearchFirstItem)([0, 1, 2, 3, 4], isGreater3, 2)).toEqual(4);
-      expect((0, _display_utils.binarySearchFirstItem)([2, 3, 4], isGreater3, 2)).toEqual(2);
-      expect((0, _display_utils.binarySearchFirstItem)([4, 5, 6], isGreater3, 1)).toEqual(1);
-    });
-  });
   describe("DOMCanvasFactory", function () {
     let canvasFactory;
     beforeAll(function () {

+ 2 - 2
lib/test/unit/jasmine-boot.js

@@ -100,11 +100,11 @@ async function initializePDFJS(callback) {
     },
 
     createElement() {
-      return document.createElement.apply(document, arguments);
+      return document.createElement(...arguments);
     },
 
     createTextNode() {
-      return document.createTextNode.apply(document, arguments);
+      return document.createTextNode(...arguments);
     },
 
     timer: new jasmine.Timer()

+ 1 - 1
lib/test/unit/scripting_spec.js

@@ -943,7 +943,7 @@ describe("Scripting", function () {
               id: refIds[3],
               value: "",
               actions: {
-                Calculate: [`AFSimple_Calculate("SUM", ["field1", "field2", "field3"]);`]
+                Calculate: [`AFSimple_Calculate("SUM", ["field1", "field2", "field3", "unknown"]);`]
               },
               type: "text"
             }]

+ 33 - 0
lib/test/unit/ui_utils_spec.js

@@ -24,6 +24,39 @@
 var _ui_utils = require("../../web/ui_utils.js");
 
 describe("ui_utils", function () {
+  describe("binary search", function () {
+    function isTrue(boolean) {
+      return boolean;
+    }
+
+    function isGreater3(number) {
+      return number > 3;
+    }
+
+    it("empty array", function () {
+      expect((0, _ui_utils.binarySearchFirstItem)([], isTrue)).toEqual(0);
+    });
+    it("single boolean entry", function () {
+      expect((0, _ui_utils.binarySearchFirstItem)([false], isTrue)).toEqual(1);
+      expect((0, _ui_utils.binarySearchFirstItem)([true], isTrue)).toEqual(0);
+    });
+    it("three boolean entries", function () {
+      expect((0, _ui_utils.binarySearchFirstItem)([true, true, true], isTrue)).toEqual(0);
+      expect((0, _ui_utils.binarySearchFirstItem)([false, true, true], isTrue)).toEqual(1);
+      expect((0, _ui_utils.binarySearchFirstItem)([false, false, true], isTrue)).toEqual(2);
+      expect((0, _ui_utils.binarySearchFirstItem)([false, false, false], isTrue)).toEqual(3);
+    });
+    it("three numeric entries", function () {
+      expect((0, _ui_utils.binarySearchFirstItem)([0, 1, 2], isGreater3)).toEqual(3);
+      expect((0, _ui_utils.binarySearchFirstItem)([2, 3, 4], isGreater3)).toEqual(2);
+      expect((0, _ui_utils.binarySearchFirstItem)([4, 5, 6], isGreater3)).toEqual(0);
+    });
+    it("three numeric entries and a start index", function () {
+      expect((0, _ui_utils.binarySearchFirstItem)([0, 1, 2, 3, 4], isGreater3, 2)).toEqual(4);
+      expect((0, _ui_utils.binarySearchFirstItem)([2, 3, 4], isGreater3, 2)).toEqual(2);
+      expect((0, _ui_utils.binarySearchFirstItem)([4, 5, 6], isGreater3, 1)).toEqual(1);
+    });
+  });
   describe("isValidRotation", function () {
     it("should reject non-integer angles", function () {
       expect((0, _ui_utils.isValidRotation)()).toEqual(false);

+ 2 - 0
lib/web/annotation_editor_layer_builder.js

@@ -37,6 +37,7 @@ class AnnotationEditorLayerBuilder {
     this.pageDiv = options.pageDiv;
     this.pdfPage = options.pdfPage;
     this.annotationStorage = options.annotationStorage || null;
+    this.accessibilityManager = options.accessibilityManager;
     this.l10n = options.l10n || _l10n_utils.NullL10n;
     this.annotationEditorLayer = null;
     this.div = null;
@@ -73,6 +74,7 @@ class AnnotationEditorLayerBuilder {
       uiManager: this.#uiManager,
       div: this.div,
       annotationStorage: this.annotationStorage,
+      accessibilityManager: this.accessibilityManager,
       pageIndex: this.pdfPage._pageIndex,
       l10n: this.l10n,
       viewport: clonedViewport

+ 5 - 2
lib/web/annotation_layer_builder.js

@@ -44,7 +44,8 @@ class AnnotationLayerBuilder {
     hasJSActionsPromise = null,
     fieldObjectsPromise = null,
     mouseState = null,
-    annotationCanvasMap = null
+    annotationCanvasMap = null,
+    accessibilityManager = null
   }) {
     this.pageDiv = pageDiv;
     this.pdfPage = pdfPage;
@@ -59,6 +60,7 @@ class AnnotationLayerBuilder {
     this._fieldObjectsPromise = fieldObjectsPromise;
     this._mouseState = mouseState;
     this._annotationCanvasMap = annotationCanvasMap;
+    this._accessibilityManager = accessibilityManager;
     this.div = null;
     this._cancelled = false;
   }
@@ -88,7 +90,8 @@ class AnnotationLayerBuilder {
       hasJSActions,
       fieldObjects,
       mouseState: this._mouseState,
-      annotationCanvasMap: this._annotationCanvasMap
+      annotationCanvasMap: this._annotationCanvasMap,
+      accessibilityManager: this._accessibilityManager
     };
 
     if (this.div) {

+ 71 - 4
lib/web/app.js

@@ -196,6 +196,8 @@ const PDFViewerApplication = {
   _wheelUnusedTicks: 0,
   _idleCallbacks: new Set(),
   _PDFBug: null,
+  _hasAnnotationEditors: false,
+  _title: document.title,
   _printAnnotationStoragePromise: null,
 
   async initialize(appConfig) {
@@ -619,12 +621,14 @@ const PDFViewerApplication = {
     this.setTitle(title);
   },
 
-  setTitle(title) {
+  setTitle(title = this._title) {
+    this._title = title;
+
     if (this.isViewerEmbedded) {
       return;
     }
 
-    document.title = title;
+    document.title = `${this._hasAnnotationEditors ? "* " : ""}${title}`;
   },
 
   get _docFilename() {
@@ -697,10 +701,12 @@ const PDFViewerApplication = {
     this._contentLength = null;
     this._saveInProgress = false;
     this._docStats = null;
+    this._hasAnnotationEditors = false;
 
     this._cancelIdleCallbacks();
 
     promises.push(this.pdfScriptingManager.destroyPromise);
+    this.setTitle();
     this.pdfSidebar.reset();
     this.pdfOutlineViewer.reset();
     this.pdfAttachmentViewer.reset();
@@ -846,6 +852,15 @@ const PDFViewerApplication = {
       await this.pdfScriptingManager.dispatchDidSave();
       this._saveInProgress = false;
     }
+
+    if (this._hasAnnotationEditors) {
+      this.externalServices.reportTelemetry({
+        type: "editing",
+        data: {
+          type: "save"
+        }
+      });
+    }
   },
 
   downloadOrSave() {
@@ -1286,7 +1301,7 @@ const PDFViewerApplication = {
     }
 
     if (pdfTitle) {
-      this.setTitle(`${pdfTitle} - ${this._contentDispositionFilename || document.title}`);
+      this.setTitle(`${pdfTitle} - ${this._contentDispositionFilename || this._title}`);
     } else if (this._contentDispositionFilename) {
       this.setTitle(this._contentDispositionFilename);
     }
@@ -1437,6 +1452,20 @@ const PDFViewerApplication = {
       window.removeEventListener("beforeunload", beforeUnload);
       delete this._annotationStorageModified;
     };
+
+    annotationStorage.onAnnotationEditor = typeStr => {
+      this._hasAnnotationEditors = !!typeStr;
+      this.setTitle();
+
+      if (typeStr) {
+        this.externalServices.reportTelemetry({
+          type: "editing",
+          data: {
+            type: typeStr
+          }
+        });
+      }
+    };
   },
 
   setInitialView(storedHash, {
@@ -1535,6 +1564,15 @@ const PDFViewerApplication = {
     this.externalServices.reportTelemetry({
       type: "print"
     });
+
+    if (this._hasAnnotationEditors) {
+      this.externalServices.reportTelemetry({
+        type: "editing",
+        data: {
+          type: "print"
+        }
+      });
+    }
   },
 
   afterPrint() {
@@ -1674,6 +1712,24 @@ const PDFViewerApplication = {
       _boundEvents
     } = this;
 
+    function addWindowResolutionChange(evt = null) {
+      if (evt) {
+        webViewerResolutionChange(evt);
+      }
+
+      const mediaQueryList = window.matchMedia(`(resolution: ${window.devicePixelRatio || 1}dppx)`);
+      mediaQueryList.addEventListener("change", addWindowResolutionChange, {
+        once: true
+      });
+
+      _boundEvents.removeWindowResolutionChange ||= function () {
+        mediaQueryList.removeEventListener("change", addWindowResolutionChange);
+        _boundEvents.removeWindowResolutionChange = null;
+      };
+    }
+
+    addWindowResolutionChange();
+
     _boundEvents.windowResize = () => {
       eventBus.dispatch("resize", {
         source: window
@@ -1834,6 +1890,7 @@ const PDFViewerApplication = {
     window.removeEventListener("beforeprint", _boundEvents.windowBeforePrint);
     window.removeEventListener("afterprint", _boundEvents.windowAfterPrint);
     window.removeEventListener("updatefromsandbox", _boundEvents.windowUpdateFromSandbox);
+    _boundEvents.removeWindowResolutionChange?.();
     _boundEvents.windowResize = null;
     _boundEvents.windowHashChange = null;
     _boundEvents.windowBeforePrint = null;
@@ -2159,8 +2216,14 @@ function webViewerSpreadModeChanged(evt) {
 function webViewerResize() {
   const {
     pdfDocument,
-    pdfViewer
+    pdfViewer,
+    pdfRenderingQueue
   } = PDFViewerApplication;
+
+  if (pdfRenderingQueue.printing && window.matchMedia("print").matches) {
+    return;
+  }
+
   pdfViewer.updateContainerHeightCss();
 
   if (!pdfDocument) {
@@ -2372,6 +2435,10 @@ function webViewerPageChanging({
   }
 }
 
+function webViewerResolutionChange(evt) {
+  PDFViewerApplication.pdfViewer.refresh();
+}
+
 function webViewerVisibilityChange(evt) {
   if (document.visibilityState === "visible") {
     setZoomDisabledTimeout();

+ 0 - 6
lib/web/app_options.js

@@ -43,12 +43,6 @@ exports.compatibilityParams = compatibilityParams;
       compatibilityParams.maxCanvasPixels = 5242880;
     }
   })();
-
-  (function checkResizeObserver() {
-    if (typeof ResizeObserver === "undefined") {
-      compatibilityParams.annotationEditorMode = -1;
-    }
-  })();
 }
 const OptionKind = {
   VIEWER: 0x02,

+ 33 - 13
lib/web/base_viewer.js

@@ -34,8 +34,6 @@ var _annotation_editor_layer_builder = require("./annotation_editor_layer_builde
 
 var _annotation_layer_builder = require("./annotation_layer_builder.js");
 
-var _app_options = require("./app_options.js");
-
 var _l10n_utils = require("./l10n_utils.js");
 
 var _pdf_page_view = require("./pdf_page_view.js");
@@ -60,7 +58,6 @@ const PagesCountLimit = {
   PAUSE_EAGER_PAGE_INIT: 250
 };
 exports.PagesCountLimit = PagesCountLimit;
-const ANNOTATION_EDITOR_MODE = _app_options.compatibilityParams.annotationEditorMode ?? _pdf.AnnotationEditorType.DISABLE;
 
 function isValidAnnotationEditorMode(mode) {
   return Object.values(_pdf.AnnotationEditorType).includes(mode) && mode !== _pdf.AnnotationEditorType.DISABLE;
@@ -146,7 +143,7 @@ class BaseViewer {
       throw new Error("Cannot initialize BaseViewer.");
     }
 
-    const viewerVersion = '2.15.349';
+    const viewerVersion = '2.16.105';
 
     if (_pdf.version !== viewerVersion) {
       throw new Error(`The API version "${_pdf.version}" does not match the Viewer version "${viewerVersion}".`);
@@ -171,7 +168,7 @@ class BaseViewer {
     this.removePageBorders = options.removePageBorders || false;
     this.textLayerMode = options.textLayerMode ?? _ui_utils.TextLayerMode.ENABLE;
     this.#annotationMode = options.annotationMode ?? _pdf.AnnotationMode.ENABLE_FORMS;
-    this.#annotationEditorMode = options.annotationEditorMode ?? ANNOTATION_EDITOR_MODE;
+    this.#annotationEditorMode = options.annotationEditorMode ?? _pdf.AnnotationEditorType.DISABLE;
     this.imageResourcesPath = options.imageResourcesPath || "";
     this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;
     this.renderer = options.renderer || _ui_utils.RendererType.CANVAS;
@@ -548,10 +545,6 @@ class BaseViewer {
         if (isPureXfa) {
           console.warn("Warning: XFA-editing is not implemented.");
         } else if (isValidAnnotationEditorMode(mode)) {
-          this.eventBus.dispatch("annotationeditormodechanged", {
-            source: this,
-            mode
-          });
           this.#annotationEditorUIManager = new _pdf.AnnotationEditorUIManager(this.container, this.eventBus);
 
           if (mode !== _pdf.AnnotationEditorType.NONE) {
@@ -622,6 +615,13 @@ class BaseViewer {
           this._scriptingManager.setDocument(pdfDocument);
         }
 
+        if (this.#annotationEditorUIManager) {
+          this.eventBus.dispatch("annotationeditormodechanged", {
+            source: this,
+            mode: this.#annotationEditorMode
+          });
+        }
+
         if (pdfDocument.loadingParams.disableAutoFetch || pagesCount > PagesCountLimit.FORCE_LAZY_PAGE_INIT) {
           this._pagesCapability.resolve();
 
@@ -1341,7 +1341,8 @@ class BaseViewer {
     viewport,
     enhanceTextSelection = false,
     eventBus,
-    highlighter
+    highlighter,
+    accessibilityManager = null
   }) {
     return new _text_layer_builder.TextLayerBuilder({
       textLayerDiv,
@@ -1349,7 +1350,8 @@ class BaseViewer {
       pageIndex,
       viewport,
       enhanceTextSelection: this.isInPresentationMode ? false : enhanceTextSelection,
-      highlighter
+      highlighter,
+      accessibilityManager
     });
   }
 
@@ -1375,7 +1377,8 @@ class BaseViewer {
     hasJSActionsPromise = this.pdfDocument?.hasJSActions(),
     mouseState = this._scriptingManager?.mouseState,
     fieldObjectsPromise = this.pdfDocument?.getFieldObjects(),
-    annotationCanvasMap = null
+    annotationCanvasMap = null,
+    accessibilityManager = null
   }) {
     return new _annotation_layer_builder.AnnotationLayerBuilder({
       pageDiv,
@@ -1390,7 +1393,8 @@ class BaseViewer {
       hasJSActionsPromise,
       mouseState,
       fieldObjectsPromise,
-      annotationCanvasMap
+      annotationCanvasMap,
+      accessibilityManager
     });
   }
 
@@ -1398,6 +1402,7 @@ class BaseViewer {
     uiManager = this.#annotationEditorUIManager,
     pageDiv,
     pdfPage,
+    accessibilityManager = null,
     l10n,
     annotationStorage = this.pdfDocument?.annotationStorage
   }) {
@@ -1406,6 +1411,7 @@ class BaseViewer {
       pageDiv,
       pdfPage,
       annotationStorage,
+      accessibilityManager,
       l10n
     });
   }
@@ -1860,6 +1866,20 @@ class BaseViewer {
     this.#annotationEditorUIManager.updateParams(type, value);
   }
 
+  refresh() {
+    if (!this.pdfDocument) {
+      return;
+    }
+
+    const updateArgs = {};
+
+    for (const pageView of this._pages) {
+      pageView.update(updateArgs);
+    }
+
+    this.update();
+  }
+
 }
 
 exports.BaseViewer = BaseViewer;

+ 10 - 4
lib/web/default_factory.js

@@ -52,7 +52,8 @@ class DefaultAnnotationLayerFactory {
     hasJSActionsPromise = null,
     mouseState = null,
     fieldObjectsPromise = null,
-    annotationCanvasMap = null
+    annotationCanvasMap = null,
+    accessibilityManager = null
   }) {
     return new _annotation_layer_builder.AnnotationLayerBuilder({
       pageDiv,
@@ -66,7 +67,8 @@ class DefaultAnnotationLayerFactory {
       hasJSActionsPromise,
       fieldObjectsPromise,
       mouseState,
-      annotationCanvasMap
+      annotationCanvasMap,
+      accessibilityManager
     });
   }
 
@@ -79,6 +81,7 @@ class DefaultAnnotationEditorLayerFactory {
     uiManager = null,
     pageDiv,
     pdfPage,
+    accessibilityManager = null,
     l10n,
     annotationStorage = null
   }) {
@@ -86,6 +89,7 @@ class DefaultAnnotationEditorLayerFactory {
       uiManager,
       pageDiv,
       pdfPage,
+      accessibilityManager,
       l10n,
       annotationStorage
     });
@@ -115,7 +119,8 @@ class DefaultTextLayerFactory {
     viewport,
     enhanceTextSelection = false,
     eventBus,
-    highlighter
+    highlighter,
+    accessibilityManager = null
   }) {
     return new _text_layer_builder.TextLayerBuilder({
       textLayerDiv,
@@ -123,7 +128,8 @@ class DefaultTextLayerFactory {
       viewport,
       enhanceTextSelection,
       eventBus,
-      highlighter
+      highlighter,
+      accessibilityManager
     });
   }
 

+ 1 - 1
lib/web/firefox_print_service.js

@@ -101,7 +101,7 @@ function FirefoxPrintService(pdfDocument, pagesOverview, printContainer, printRe
   this.printContainer = printContainer;
   this._printResolution = printResolution || 150;
   this._optionalContentConfigPromise = optionalContentConfigPromise || pdfDocument.getOptionalContentConfig();
-  this._optionalContentConfigPromise = printAnnotationStoragePromise || Promise.resolve();
+  this._printAnnotationStoragePromise = printAnnotationStoragePromise || Promise.resolve();
 }
 
 FirefoxPrintService.prototype = {

+ 6 - 3
lib/web/interfaces.js

@@ -87,7 +87,8 @@ class IPDFTextLayerFactory {
     viewport,
     enhanceTextSelection = false,
     eventBus,
-    highlighter
+    highlighter,
+    accessibilityManager
   }) {}
 
 }
@@ -106,7 +107,8 @@ class IPDFAnnotationLayerFactory {
     hasJSActionsPromise = null,
     mouseState = null,
     fieldObjectsPromise = null,
-    annotationCanvasMap = null
+    annotationCanvasMap = null,
+    accessibilityManager = null
   }) {}
 
 }
@@ -119,7 +121,8 @@ class IPDFAnnotationEditorLayerFactory {
     pageDiv,
     pdfPage,
     l10n,
-    annotationStorage = null
+    annotationStorage = null,
+    accessibilityManager
   }) {}
 
 }

+ 21 - 3
lib/web/password_prompt.js

@@ -29,6 +29,7 @@ exports.PasswordPrompt = void 0;
 var _pdf = require("../pdf");
 
 class PasswordPrompt {
+  #activeCapability = null;
   #updateCallback = null;
   #reason = null;
 
@@ -42,7 +43,7 @@ class PasswordPrompt {
     this.l10n = l10n;
     this._isViewerEmbedded = isViewerEmbedded;
     this.submitButton.addEventListener("click", this.#verify.bind(this));
-    this.cancelButton.addEventListener("click", this.#cancel.bind(this));
+    this.cancelButton.addEventListener("click", this.close.bind(this));
     this.input.addEventListener("keydown", e => {
       if (e.keyCode === 13) {
         this.#verify();
@@ -53,7 +54,19 @@ class PasswordPrompt {
   }
 
   async open() {
-    await this.overlayManager.open(this.dialog);
+    if (this.#activeCapability) {
+      await this.#activeCapability.promise;
+    }
+
+    this.#activeCapability = (0, _pdf.createPromiseCapability)();
+
+    try {
+      await this.overlayManager.open(this.dialog);
+    } catch (ex) {
+      this.#activeCapability = null;
+      throw ex;
+    }
+
     const passwordIncorrect = this.#reason === _pdf.PasswordResponses.INCORRECT_PASSWORD;
 
     if (!this._isViewerEmbedded || passwordIncorrect) {
@@ -79,6 +92,7 @@ class PasswordPrompt {
 
   #cancel() {
     this.#invokeCallback(new Error("PasswordPrompt cancelled."));
+    this.#activeCapability.resolve();
   }
 
   #invokeCallback(password) {
@@ -92,7 +106,11 @@ class PasswordPrompt {
     this.#updateCallback = null;
   }
 
-  setUpdateCallback(updateCallback, reason) {
+  async setUpdateCallback(updateCallback, reason) {
+    if (this.#activeCapability) {
+      await this.#activeCapability.promise;
+    }
+
     this.#updateCallback = updateCallback;
     this.#reason = reason;
   }

+ 4 - 4
lib/web/pdf_find_controller.js

@@ -26,12 +26,12 @@ Object.defineProperty(exports, "__esModule", {
 });
 exports.PDFFindController = exports.FindState = void 0;
 
+var _ui_utils = require("./ui_utils.js");
+
 var _pdf = require("../pdf");
 
 var _pdf_find_utils = require("./pdf_find_utils.js");
 
-var _ui_utils = require("./ui_utils.js");
-
 const FindState = {
   FOUND: 0,
   NOT_FOUND: 1,
@@ -206,13 +206,13 @@ function getOriginalIndex(diffs, pos, len) {
 
   const start = pos;
   const end = pos + len;
-  let i = (0, _pdf.binarySearchFirstItem)(diffs, x => x[0] >= start);
+  let i = (0, _ui_utils.binarySearchFirstItem)(diffs, x => x[0] >= start);
 
   if (diffs[i][0] > start) {
     --i;
   }
 
-  let j = (0, _pdf.binarySearchFirstItem)(diffs, x => x[0] >= end, i);
+  let j = (0, _ui_utils.binarySearchFirstItem)(diffs, x => x[0] >= end, i);
 
   if (diffs[j][0] > end) {
     --j;

+ 16 - 9
lib/web/pdf_page_view.js

@@ -34,6 +34,8 @@ var _app_options = require("./app_options.js");
 
 var _l10n_utils = require("./l10n_utils.js");
 
+var _text_accessibility = require("./text_accessibility.js");
+
 const MAX_CANVAS_PIXELS = _app_options.compatibilityParams.maxCanvasPixels || 16777216;
 
 class PDFPageView {
@@ -144,6 +146,7 @@ class PDFPageView {
     try {
       await this.annotationLayer.render(this.viewport, "display");
     } catch (ex) {
+      console.error(`_renderAnnotationLayer: "${ex}".`);
       error = ex;
     } finally {
       this.eventBus.dispatch("annotationlayerrendered", {
@@ -160,6 +163,7 @@ class PDFPageView {
     try {
       await this.annotationEditorLayer.render(this.viewport, "display");
     } catch (ex) {
+      console.error(`_renderAnnotationEditorLayer: "${ex}".`);
       error = ex;
     } finally {
       this.eventBus.dispatch("annotationeditorlayerrendered", {
@@ -180,6 +184,7 @@ class PDFPageView {
         this._buildXfaTextContentItems(result.textDivs);
       }
     } catch (ex) {
+      console.error(`_renderXfaLayer: "${ex}".`);
       error = ex;
     } finally {
       this.eventBus.dispatch("xfalayerrendered", {
@@ -570,6 +575,7 @@ class PDFPageView {
     let textLayer = null;
 
     if (this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && this.textLayerFactory) {
+      this._accessibilityManager ||= new _text_accessibility.TextAccessibilityManager();
       const textLayerDiv = document.createElement("div");
       textLayerDiv.className = "textLayer";
       textLayerDiv.style.width = canvasWrapper.style.width;
@@ -587,7 +593,8 @@ class PDFPageView {
         viewport: this.viewport,
         enhanceTextSelection: this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE,
         eventBus: this.eventBus,
-        highlighter: this.textHighlighter
+        highlighter: this.textHighlighter,
+        accessibilityManager: this._accessibilityManager
       });
     }
 
@@ -601,7 +608,8 @@ class PDFPageView {
         imageResourcesPath: this.imageResourcesPath,
         renderForms: this.#annotationMode === _pdf.AnnotationMode.ENABLE_FORMS,
         l10n: this.l10n,
-        annotationCanvasMap: this._annotationCanvasMap
+        annotationCanvasMap: this._annotationCanvasMap,
+        accessibilityManager: this._accessibilityManager
       });
     }
 
@@ -681,7 +689,8 @@ class PDFPageView {
               this.annotationEditorLayer ||= this.annotationEditorLayerFactory.createAnnotationEditorLayerBuilder({
                 pageDiv: div,
                 pdfPage,
-                l10n: this.l10n
+                l10n: this.l10n,
+                accessibilityManager: this._accessibilityManager
               });
 
               this._renderAnnotationEditorLayer();
@@ -694,12 +703,10 @@ class PDFPageView {
     });
 
     if (this.xfaLayerFactory) {
-      if (!this.xfaLayer) {
-        this.xfaLayer = this.xfaLayerFactory.createXfaLayerBuilder({
-          pageDiv: div,
-          pdfPage
-        });
-      }
+      this.xfaLayer ||= this.xfaLayerFactory.createXfaLayerBuilder({
+        pageDiv: div,
+        pdfPage
+      });
 
       this._renderXfaLayer();
     }

+ 1 - 0
lib/web/pdf_presentation_mode.js

@@ -88,6 +88,7 @@ class PDFPresentationMode {
 
     try {
       await promise;
+      pdfViewer.focus();
       return true;
     } catch (reason) {
       this.#removeFullscreenChangeListeners();

+ 6 - 1
lib/web/pdf_thumbnail_view.js

@@ -322,7 +322,8 @@ class PDFThumbnailView {
 
     const {
       thumbnailCanvas: canvas,
-      pdfPage
+      pdfPage,
+      scale
     } = pageView;
 
     if (!canvas) {
@@ -333,6 +334,10 @@ class PDFThumbnailView {
       this.setPdfPage(pdfPage);
     }
 
+    if (scale < this.scale) {
+      return;
+    }
+
     this.renderingState = _ui_utils.RenderingStates.FINISHED;
 
     this._convertCanvasToImage(canvas);

+ 20 - 2
lib/web/pdf_viewer.component.js

@@ -132,12 +132,30 @@ Object.defineProperty(exports, "ProgressBar", {
     return _ui_utils.ProgressBar;
   }
 });
+Object.defineProperty(exports, "RenderingStates", {
+  enumerable: true,
+  get: function () {
+    return _ui_utils.RenderingStates;
+  }
+});
+Object.defineProperty(exports, "ScrollMode", {
+  enumerable: true,
+  get: function () {
+    return _ui_utils.ScrollMode;
+  }
+});
 Object.defineProperty(exports, "SimpleLinkService", {
   enumerable: true,
   get: function () {
     return _pdf_link_service.SimpleLinkService;
   }
 });
+Object.defineProperty(exports, "SpreadMode", {
+  enumerable: true,
+  get: function () {
+    return _ui_utils.SpreadMode;
+  }
+});
 Object.defineProperty(exports, "StructTreeLayerBuilder", {
   enumerable: true,
   get: function () {
@@ -195,5 +213,5 @@ var _text_layer_builder = require("./text_layer_builder.js");
 
 var _xfa_layer_builder = require("./xfa_layer_builder.js");
 
-const pdfjsVersion = '2.15.349';
-const pdfjsBuild = 'b8aa9c622';
+const pdfjsVersion = '2.16.105';
+const pdfjsBuild = '172ccdbe5';

+ 1 - 1
lib/web/secondary_toolbar.js

@@ -149,11 +149,11 @@ class SecondaryToolbar {
     };
     this.eventBus = eventBus;
     this.opened = false;
-    this.reset();
     this.#bindClickListeners();
     this.#bindCursorToolsListener(options);
     this.#bindScrollModeListener(options);
     this.#bindSpreadModeListener(options);
+    this.reset();
   }
 
   get isOpen() {

+ 221 - 0
lib/web/text_accessibility.js

@@ -0,0 +1,221 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * JavaScript code in this page
+ *
+ * Copyright 2022 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @licend The above is the entire license notice for the
+ * JavaScript code in this page
+ */
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports.TextAccessibilityManager = void 0;
+
+var _ui_utils = require("./ui_utils.js");
+
+class TextAccessibilityManager {
+  #enabled = false;
+  #textChildren = null;
+  #textNodes = new Map();
+  #waitingElements = new Map();
+
+  setTextMapping(textDivs) {
+    this.#textChildren = textDivs;
+  }
+
+  static #compareElementPositions(e1, e2) {
+    const rect1 = e1.getBoundingClientRect();
+    const rect2 = e2.getBoundingClientRect();
+
+    if (rect1.width === 0 && rect1.height === 0) {
+      return +1;
+    }
+
+    if (rect2.width === 0 && rect2.height === 0) {
+      return -1;
+    }
+
+    const top1 = rect1.y;
+    const bot1 = rect1.y + rect1.height;
+    const mid1 = rect1.y + rect1.height / 2;
+    const top2 = rect2.y;
+    const bot2 = rect2.y + rect2.height;
+    const mid2 = rect2.y + rect2.height / 2;
+
+    if (mid1 <= top2 && mid2 >= bot1) {
+      return -1;
+    }
+
+    if (mid2 <= top1 && mid1 >= bot2) {
+      return +1;
+    }
+
+    const centerX1 = rect1.x + rect1.width / 2;
+    const centerX2 = rect2.x + rect2.width / 2;
+    return centerX1 - centerX2;
+  }
+
+  enable() {
+    if (this.#enabled) {
+      throw new Error("TextAccessibilityManager is already enabled.");
+    }
+
+    if (!this.#textChildren) {
+      throw new Error("Text divs and strings have not been set.");
+    }
+
+    this.#enabled = true;
+    this.#textChildren = this.#textChildren.slice();
+    this.#textChildren.sort(TextAccessibilityManager.#compareElementPositions);
+
+    if (this.#textNodes.size > 0) {
+      const textChildren = this.#textChildren;
+
+      for (const [id, nodeIndex] of this.#textNodes) {
+        const element = document.getElementById(id);
+
+        if (!element) {
+          this.#textNodes.delete(id);
+          continue;
+        }
+
+        this.#addIdToAriaOwns(id, textChildren[nodeIndex]);
+      }
+    }
+
+    for (const [element, isRemovable] of this.#waitingElements) {
+      this.addPointerInTextLayer(element, isRemovable);
+    }
+
+    this.#waitingElements.clear();
+  }
+
+  disable() {
+    if (!this.#enabled) {
+      return;
+    }
+
+    this.#waitingElements.clear();
+    this.#textChildren = null;
+    this.#enabled = false;
+  }
+
+  removePointerInTextLayer(element) {
+    if (!this.#enabled) {
+      this.#waitingElements.delete(element);
+      return;
+    }
+
+    const children = this.#textChildren;
+
+    if (!children || children.length === 0) {
+      return;
+    }
+
+    const {
+      id
+    } = element;
+    const nodeIndex = this.#textNodes.get(id);
+
+    if (nodeIndex === undefined) {
+      return;
+    }
+
+    const node = children[nodeIndex];
+    this.#textNodes.delete(id);
+    let owns = node.getAttribute("aria-owns");
+
+    if (owns?.includes(id)) {
+      owns = owns.split(" ").filter(x => x !== id).join(" ");
+
+      if (owns) {
+        node.setAttribute("aria-owns", owns);
+      } else {
+        node.removeAttribute("aria-owns");
+        node.setAttribute("role", "presentation");
+      }
+    }
+  }
+
+  #addIdToAriaOwns(id, node) {
+    const owns = node.getAttribute("aria-owns");
+
+    if (!owns?.includes(id)) {
+      node.setAttribute("aria-owns", owns ? `${owns} ${id}` : id);
+    }
+
+    node.removeAttribute("role");
+  }
+
+  addPointerInTextLayer(element, isRemovable) {
+    const {
+      id
+    } = element;
+
+    if (!id) {
+      return;
+    }
+
+    if (!this.#enabled) {
+      this.#waitingElements.set(element, isRemovable);
+      return;
+    }
+
+    if (isRemovable) {
+      this.removePointerInTextLayer(element);
+    }
+
+    const children = this.#textChildren;
+
+    if (!children || children.length === 0) {
+      return;
+    }
+
+    const index = (0, _ui_utils.binarySearchFirstItem)(children, node => TextAccessibilityManager.#compareElementPositions(element, node) < 0);
+    const nodeIndex = Math.max(0, index - 1);
+    this.#addIdToAriaOwns(id, children[nodeIndex]);
+    this.#textNodes.set(id, nodeIndex);
+  }
+
+  moveElementInDOM(container, element, contentElement, isRemovable) {
+    this.addPointerInTextLayer(contentElement, isRemovable);
+
+    if (!container.hasChildNodes()) {
+      container.append(element);
+      return;
+    }
+
+    const children = Array.from(container.childNodes).filter(node => node !== element);
+
+    if (children.length === 0) {
+      return;
+    }
+
+    const elementToCompare = contentElement || element;
+    const index = (0, _ui_utils.binarySearchFirstItem)(children, node => TextAccessibilityManager.#compareElementPositions(elementToCompare, node) < 0);
+
+    if (index === 0) {
+      children[0].before(element);
+    } else {
+      children[index - 1].after(element);
+    }
+  }
+
+}
+
+exports.TextAccessibilityManager = TextAccessibilityManager;

+ 6 - 1
lib/web/text_layer_builder.js

@@ -37,7 +37,8 @@ class TextLayerBuilder {
     pageIndex,
     viewport,
     highlighter = null,
-    enhanceTextSelection = false
+    enhanceTextSelection = false,
+    accessibilityManager = null
   }) {
     this.textLayerDiv = textLayerDiv;
     this.eventBus = eventBus;
@@ -51,6 +52,7 @@ class TextLayerBuilder {
     this.textLayerRenderTask = null;
     this.highlighter = highlighter;
     this.enhanceTextSelection = enhanceTextSelection;
+    this.accessibilityManager = accessibilityManager;
 
     this._bindMouse();
   }
@@ -79,6 +81,7 @@ class TextLayerBuilder {
     this.cancel();
     this.textDivs.length = 0;
     this.highlighter?.setTextMapping(this.textDivs, this.textContentItemsStr);
+    this.accessibilityManager?.setTextMapping(this.textDivs);
     const textLayerFrag = document.createDocumentFragment();
     this.textLayerRenderTask = (0, _pdf.renderTextLayer)({
       textContent: this.textContent,
@@ -96,6 +99,7 @@ class TextLayerBuilder {
       this._finishRendering();
 
       this.highlighter?.enable();
+      this.accessibilityManager?.enable();
     }, function (reason) {});
   }
 
@@ -106,6 +110,7 @@ class TextLayerBuilder {
     }
 
     this.highlighter?.disable();
+    this.accessibilityManager?.disable();
   }
 
   setTextContentStream(readableStream) {

+ 28 - 40
lib/web/toolbar.js

@@ -33,6 +33,8 @@ var _pdf = require("../pdf");
 const PAGE_NUMBER_LOADING_INDICATOR = "visiblePageIsLoading";
 
 class Toolbar {
+  #wasLocalized = false;
+
   constructor(options, eventBus, l10n) {
     this.toolbar = options.container;
     this.eventBus = eventBus;
@@ -61,23 +63,29 @@ class Toolbar {
     }, {
       element: options.viewBookmark,
       eventName: null
-    }, {
-      element: options.editorNoneButton,
-      eventName: "switchannotationeditormode",
-      eventDetails: {
-        mode: _pdf.AnnotationEditorType.NONE
-      }
     }, {
       element: options.editorFreeTextButton,
       eventName: "switchannotationeditormode",
       eventDetails: {
-        mode: _pdf.AnnotationEditorType.FREETEXT
+        get mode() {
+          const {
+            classList
+          } = options.editorFreeTextButton;
+          return classList.contains("toggled") ? _pdf.AnnotationEditorType.NONE : _pdf.AnnotationEditorType.FREETEXT;
+        }
+
       }
     }, {
       element: options.editorInkButton,
       eventName: "switchannotationeditormode",
       eventDetails: {
-        mode: _pdf.AnnotationEditorType.INK
+        get mode() {
+          const {
+            classList
+          } = options.editorInkButton;
+          return classList.contains("toggled") ? _pdf.AnnotationEditorType.NONE : _pdf.AnnotationEditorType.INK;
+        }
+
       }
     }];
     this.buttons.push({
@@ -92,38 +100,28 @@ class Toolbar {
       previous: options.previous,
       next: options.next,
       zoomIn: options.zoomIn,
-      zoomOut: options.zoomOut,
-      editorNoneButton: options.editorNoneButton,
-      editorFreeTextButton: options.editorFreeTextButton,
-      editorFreeTextParamsToolbar: options.editorFreeTextParamsToolbar,
-      editorInkButton: options.editorInkButton,
-      editorInkParamsToolbar: options.editorInkParamsToolbar
+      zoomOut: options.zoomOut
     };
-    this._wasLocalized = false;
+    this.#bindListeners(options);
     this.reset();
-
-    this._bindListeners(options);
   }
 
   setPageNumber(pageNumber, pageLabel) {
     this.pageNumber = pageNumber;
     this.pageLabel = pageLabel;
-
-    this._updateUIState(false);
+    this.#updateUIState(false);
   }
 
   setPagesCount(pagesCount, hasPageLabels) {
     this.pagesCount = pagesCount;
     this.hasPageLabels = hasPageLabels;
-
-    this._updateUIState(true);
+    this.#updateUIState(true);
   }
 
   setPageScale(pageScaleValue, pageScale) {
     this.pageScaleValue = (pageScaleValue || pageScale).toString();
     this.pageScale = pageScale;
-
-    this._updateUIState(false);
+    this.#updateUIState(false);
   }
 
   reset() {
@@ -133,16 +131,14 @@ class Toolbar {
     this.pagesCount = 0;
     this.pageScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;
     this.pageScale = _ui_utils.DEFAULT_SCALE;
-
-    this._updateUIState(true);
-
+    this.#updateUIState(true);
     this.updateLoadingIndicatorState();
     this.eventBus.dispatch("toolbarreset", {
       source: this
     });
   }
 
-  _bindListeners(options) {
+  #bindListeners(options) {
     const {
       pageNumber,
       scaleSelect
@@ -200,17 +196,15 @@ class Toolbar {
     scaleSelect.oncontextmenu = _ui_utils.noContextMenuHandler;
 
     this.eventBus._on("localized", () => {
-      this._wasLocalized = true;
+      this.#wasLocalized = true;
       this.#adjustScaleWidth();
-
-      this._updateUIState(true);
+      this.#updateUIState(true);
     });
 
     this.#bindEditorToolsListener(options);
   }
 
   #bindEditorToolsListener({
-    editorNoneButton,
     editorFreeTextButton,
     editorFreeTextParamsToolbar,
     editorInkButton,
@@ -218,9 +212,6 @@ class Toolbar {
   }) {
     const editorModeChanged = (evt, disableButtons = false) => {
       const editorButtons = [{
-        mode: _pdf.AnnotationEditorType.NONE,
-        button: editorNoneButton
-      }, {
         mode: _pdf.AnnotationEditorType.FREETEXT,
         button: editorFreeTextButton,
         toolbar: editorFreeTextParamsToolbar
@@ -239,10 +230,7 @@ class Toolbar {
         button.classList.toggle("toggled", checked);
         button.setAttribute("aria-checked", checked);
         button.disabled = disableButtons;
-
-        if (toolbar) {
-          toolbar.classList.toggle("hidden", !checked);
-        }
+        toolbar?.classList.toggle("hidden", !checked);
       }
     };
 
@@ -257,8 +245,8 @@ class Toolbar {
     });
   }
 
-  _updateUIState(resetNumPages = false) {
-    if (!this._wasLocalized) {
+  #updateUIState(resetNumPages = false) {
+    if (!this.#wasLocalized) {
       return;
     }
 

+ 28 - 4
lib/web/ui_utils.js

@@ -29,6 +29,7 @@ exports.apiPageLayoutToViewerModes = apiPageLayoutToViewerModes;
 exports.apiPageModeToSidebarView = apiPageModeToSidebarView;
 exports.approximateFraction = approximateFraction;
 exports.backtrackBeforeAllVisibleElements = backtrackBeforeAllVisibleElements;
+exports.binarySearchFirstItem = binarySearchFirstItem;
 exports.docStyle = void 0;
 exports.getActiveOrFocusedElement = getActiveOrFocusedElement;
 exports.getPageSizeInches = getPageSizeInches;
@@ -45,9 +46,6 @@ exports.removeNullCharacters = removeNullCharacters;
 exports.roundToDivide = roundToDivide;
 exports.scrollIntoView = scrollIntoView;
 exports.watchScroll = watchScroll;
-
-var _pdf = require("../pdf");
-
 const DEFAULT_SCALE_VALUE = "auto";
 exports.DEFAULT_SCALE_VALUE = DEFAULT_SCALE_VALUE;
 const DEFAULT_SCALE = 1.0;
@@ -234,6 +232,32 @@ function removeNullCharacters(str, replaceInvisible = false) {
   return str.replace(NullCharactersRegExp, "");
 }
 
+function binarySearchFirstItem(items, condition, start = 0) {
+  let minIndex = start;
+  let maxIndex = items.length - 1;
+
+  if (maxIndex < 0 || !condition(items[maxIndex])) {
+    return items.length;
+  }
+
+  if (condition(items[minIndex])) {
+    return minIndex;
+  }
+
+  while (minIndex < maxIndex) {
+    const currentIndex = minIndex + maxIndex >> 1;
+    const currentItem = items[currentIndex];
+
+    if (condition(currentItem)) {
+      maxIndex = currentIndex;
+    } else {
+      minIndex = currentIndex + 1;
+    }
+  }
+
+  return minIndex;
+}
+
 function approximateFraction(x) {
   if (Math.floor(x) === x) {
     return [x, 1];
@@ -356,7 +380,7 @@ function getVisibleElements({
   const visible = [],
         ids = new Set(),
         numViews = views.length;
-  let firstVisibleElementInd = (0, _pdf.binarySearchFirstItem)(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop);
+  let firstVisibleElementInd = binarySearchFirstItem(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop);
 
   if (firstVisibleElementInd > 0 && firstVisibleElementInd < numViews && !horizontal) {
     firstVisibleElementInd = backtrackBeforeAllVisibleElements(firstVisibleElementInd, views, top);

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "pdfjs-dist",
-  "version": "2.15.349",
+  "version": "2.16.105",
   "main": "build/pdf.js",
   "types": "types/src/pdf.d.ts",
   "description": "Generic build of Mozilla's PDF.js library.",

+ 3 - 2
types/src/display/annotation_layer.d.ts

@@ -63,6 +63,7 @@ export type AnnotationLayerParameters = {
  * @property {Map<string, HTMLCanvasElement>} [annotationCanvasMap]
  */
 export class AnnotationLayer {
+    static "__#26@#appendElement"(element: any, id: any, div: any, accessibilityManager: any): void;
     /**
      * Render a new annotation layer with all annotation elements.
      *
@@ -83,7 +84,7 @@ export class AnnotationLayer {
      * @param {HTMLDivElement} div
      * @param {PageViewport} viewport
      */
-    static "__#25@#setDimensions"(div: HTMLDivElement, { width, height, rotation }: PageViewport): void;
-    static "__#25@#setAnnotationCanvasMap"(div: any, annotationCanvasMap: any): void;
+    static "__#26@#setDimensions"(div: HTMLDivElement, { width, height, rotation }: PageViewport): void;
+    static "__#26@#setAnnotationCanvasMap"(div: any, annotationCanvasMap: any): void;
 }
 import { AnnotationStorage } from "./annotation_storage.js";

+ 2 - 1
types/src/display/annotation_storage.d.ts

@@ -11,6 +11,7 @@ export class AnnotationStorage {
     _modified: boolean;
     onSetModified: any;
     onResetModified: any;
+    onAnnotationEditor: any;
     /**
      * Get the value for a given key if it exists, or return the default value.
      *
@@ -34,7 +35,7 @@ export class AnnotationStorage {
      * Remove a value from the storage.
      * @param {string} key
      */
-    removeKey(key: string): void;
+    remove(key: string): void;
     /**
      * Set the value for a given key
      *

+ 19 - 9
types/src/display/api.d.ts

@@ -1,4 +1,5 @@
 export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
+export type BinaryData = TypedArray | ArrayBuffer | Array<number> | string;
 export type RefProxy = {
     num: number;
     gen: number;
@@ -12,11 +13,11 @@ export type DocumentInitParameters = {
      */
     url?: string | URL | undefined;
     /**
-     * - Binary PDF data. Use
-     * typed arrays (Uint8Array) to improve the memory usage. If PDF data is
+     * - Binary PDF data.
+     * Use typed arrays (Uint8Array) to improve the memory usage. If PDF data is
      * BASE64-encoded, use `atob()` to convert it to a binary string first.
      */
-    data?: string | number[] | TypedArray | undefined;
+    data?: BinaryData | undefined;
     /**
      * - Basic authentication headers.
      */
@@ -186,6 +187,7 @@ export type DocumentInitParameters = {
      */
     pdfBug?: boolean | undefined;
 };
+export type GetDocumentParameters = string | URL | TypedArray | ArrayBuffer | PDFDataRangeTransport | DocumentInitParameters;
 export type IPDFStreamFactory = Function;
 export type OnProgressParameters = {
     /**
@@ -515,6 +517,9 @@ export let DefaultStandardFontDataFactory: typeof DOMStandardFontDataFactory;
  *            Float64Array
  * } TypedArray
  */
+/**
+ * @typedef { TypedArray | ArrayBuffer | Array<number> | string } BinaryData
+ */
 /**
  * @typedef {Object} RefProxy
  * @property {number} num
@@ -524,10 +529,10 @@ export let DefaultStandardFontDataFactory: typeof DOMStandardFontDataFactory;
  * Document initialization / loading parameters object.
  *
  * @typedef {Object} DocumentInitParameters
- * @property {string|URL} [url] - The URL of the PDF.
- * @property {TypedArray|Array<number>|string} [data] - Binary PDF data. Use
- *    typed arrays (Uint8Array) to improve the memory usage. If PDF data is
- *    BASE64-encoded, use `atob()` to convert it to a binary string first.
+ * @property {string | URL} [url] - The URL of the PDF.
+ * @property {BinaryData} [data] - Binary PDF data.
+ *   Use typed arrays (Uint8Array) to improve the memory usage. If PDF data is
+ *   BASE64-encoded, use `atob()` to convert it to a binary string first.
  * @property {Object} [httpHeaders] - Basic authentication headers.
  * @property {boolean} [withCredentials] - Indicates whether or not
  *   cross-site Access-Control requests should be made using credentials such
@@ -613,6 +618,11 @@ export let DefaultStandardFontDataFactory: typeof DOMStandardFontDataFactory;
  * @property {boolean} [pdfBug] - Enables special hooks for debugging PDF.js
  *   (see `web/debugger.js`). The default value is `false`.
  */
+/**
+ * @typedef { string | URL | TypedArray | ArrayBuffer |
+ *            PDFDataRangeTransport | DocumentInitParameters
+ * } GetDocumentParameters
+ */
 /**
  * This is the main entry point for loading a PDF and interacting with it.
  *
@@ -620,12 +630,12 @@ export let DefaultStandardFontDataFactory: typeof DOMStandardFontDataFactory;
  * XHR as fallback) is used, which means it must follow same origin rules,
  * e.g. no cross-domain requests without CORS.
  *
- * @param {string|URL|TypedArray|PDFDataRangeTransport|DocumentInitParameters}
+ * @param {GetDocumentParameters}
  *   src - Can be a URL where a PDF file is located, a typed array (Uint8Array)
  *         already populated with data, or a parameter object.
  * @returns {PDFDocumentLoadingTask}
  */
-export function getDocument(src: string | URL | TypedArray | PDFDataRangeTransport | DocumentInitParameters): PDFDocumentLoadingTask;
+export function getDocument(src: GetDocumentParameters): PDFDocumentLoadingTask;
 export class LoopbackPort {
     _listeners: any[];
     _deferred: Promise<void>;

+ 1 - 2
types/src/display/canvas.d.ts

@@ -149,7 +149,6 @@ export class CanvasGraphics {
     getSinglePixelWidth(): number;
     getScaleForStroking(): number[];
     rescaleAndStroke(saveRestore: any): void;
-    getCanvasPosition(x: any, y: any): any[];
     isContentVisible(): boolean;
     #private;
 }
@@ -200,7 +199,7 @@ declare class CachedCanvases {
     constructor(canvasFactory: any);
     canvasFactory: any;
     cache: any;
-    getCanvas(id: any, width: any, height: any, trackTransform: any): any;
+    getCanvas(id: any, width: any, height: any): any;
     delete(id: any): void;
     clear(): void;
 }

+ 3 - 10
types/src/display/display_utils.d.ts

@@ -55,16 +55,7 @@ export type PageViewportCloneParameters = {
      */
     dontFlip?: boolean | undefined;
 };
-/**
- * Use binary search to find the index of the first item in a given array which
- * passes a given condition. The items are expected to be sorted in the sense
- * that if the condition is true for one item in the array, then it is also true
- * for all following items.
- *
- * @returns {number} Index of the first array element to pass the test,
- *                   or |items.length| if no such element exists.
- */
-export function binarySearchFirstItem(items: any, condition: any, start?: number): number;
+export const AnnotationPrefix: "pdfjs_internal_id_";
 export function deprecated(details: any): void;
 export class DOMCanvasFactory extends BaseCanvasFactory {
     constructor({ ownerDocument }?: {
@@ -98,6 +89,8 @@ export class DOMSVGFactory extends BaseSVGFactory {
     _createSVG(type: any): any;
 }
 export function getColorValues(colors: any): void;
+export function getCurrentTransform(ctx: any): any[];
+export function getCurrentTransformInverse(ctx: any): any[];
 /**
  * Gets the filename from a given URL.
  * @param {string} url

+ 4 - 30
types/src/display/editor/annotation_editor_layer.d.ts

@@ -1,6 +1,7 @@
 export type AnnotationEditor = import("./editor.js").AnnotationEditor;
 export type AnnotationEditorUIManager = import("./tools.js").AnnotationEditorUIManager;
 export type AnnotationStorage = import("../annotation_storage.js").AnnotationStorage;
+export type TextAccessibilityManager = any;
 export type IL10n = any;
 export type AnnotationEditorLayerOptions = {
     mode: Object;
@@ -8,6 +9,7 @@ export type AnnotationEditorLayerOptions = {
     uiManager: AnnotationEditorUIManager;
     enabled: boolean;
     annotationStorage: AnnotationStorage;
+    accessibilityManager?: any;
     pageIndex: number;
     l10n: any;
 };
@@ -18,6 +20,7 @@ export type AnnotationEditorLayerOptions = {
  * @property {AnnotationEditorUIManager} uiManager
  * @property {boolean} enabled
  * @property {AnnotationStorage} annotationStorage
+ * @property {TextAccessibilityManager} [accessibilityManager]
  * @property {number} pageIndex
  * @property {IL10n} l10n
  */
@@ -26,15 +29,6 @@ export type AnnotationEditorLayerOptions = {
  */
 export class AnnotationEditorLayer {
     static _initialized: boolean;
-    /**
-     * Compare the positions of two elements, it must correspond to
-     * the visual ordering.
-     *
-     * @param {HTMLElement} e1
-     * @param {HTMLElement} e2
-     * @returns {number}
-     */
-    static "__#3@#compareElementPositions"(e1: HTMLElement, e2: HTMLElement): number;
     /**
      * @param {AnnotationEditorLayerOptions} options
      */
@@ -42,7 +36,6 @@ export class AnnotationEditorLayer {
     annotationStorage: import("../annotation_storage.js").AnnotationStorage;
     pageIndex: number;
     div: HTMLDivElement;
-    get textLayerElements(): any;
     /**
      * Update the toolbar if it's required to reflect the tool currently used.
      * @param {number} mode
@@ -87,31 +80,12 @@ export class AnnotationEditorLayer {
      * @param {AnnotationEditor} editor
      */
     remove(editor: AnnotationEditor): void;
-    /**
-     * Function called when the text layer has finished rendering.
-     */
-    onTextLayerRendered(): void;
-    /**
-     * Remove an aria-owns id from a node in the text layer.
-     * @param {AnnotationEditor} editor
-     */
-    removePointerInTextLayer(editor: AnnotationEditor): void;
-    /**
-     * Find the text node which is the nearest and add an aria-owns attribute
-     * in order to correctly position this editor in the text flow.
-     * @param {AnnotationEditor} editor
-     */
-    addPointerInTextLayer(editor: AnnotationEditor): void;
-    /**
-     * Move a div in the DOM in order to respect the visual order.
-     * @param {HTMLDivElement} div
-     */
-    moveDivInDOM(editor: any): void;
     /**
      * Add a new editor in the current view.
      * @param {AnnotationEditor} editor
      */
     add(editor: AnnotationEditor): void;
+    moveEditorInDOM(editor: any): void;
     /**
      * Add an editor in the annotation storage.
      * @param {AnnotationEditor} editor

+ 0 - 5
types/src/display/editor/editor.d.ts

@@ -203,11 +203,6 @@ export class AnnotationEditor {
      * their properties.
      */
     enableEditing(): void;
-    /**
-     * Get the id to use in aria-owns when a link is done in the text layer.
-     * @returns {string}
-     */
-    getIdForTextLayer(): string;
     /**
      * Get some properties to update in the UI.
      * @returns {Object}

+ 1 - 0
types/src/display/editor/freetext.d.ts

@@ -9,6 +9,7 @@ export class FreeTextEditor extends AnnotationEditor {
     static _defaultColor: null;
     static _defaultFontSize: number;
     static _keyboardManager: KeyboardManager;
+    static _type: string;
     static initialize(l10n: any): void;
     static updateDefaultParams(type: any, value: any): void;
     static get defaultPropertiesToUpdate(): any[][];

+ 1 - 0
types/src/display/editor/ink.d.ts

@@ -6,6 +6,7 @@ export class InkEditor extends AnnotationEditor {
     static _defaultOpacity: number;
     static _defaultThickness: number;
     static _l10nPromise: any;
+    static _type: string;
     static initialize(l10n: any): void;
     static updateDefaultParams(type: any, value: any): void;
     static get defaultPropertiesToUpdate(): any[][];

+ 0 - 3
types/src/display/editor/tools.d.ts

@@ -15,9 +15,6 @@ export class AnnotationEditorUIManager {
     onPageChanging({ pageNumber }: {
         pageNumber: any;
     }): void;
-    onTextLayerRendered({ pageNumber }: {
-        pageNumber: any;
-    }): void;
     focusMainContainer(): void;
     /**
      * Keydown callback.

+ 2 - 2
types/src/display/fetch_stream.d.ts

@@ -23,7 +23,7 @@ declare class PDFFetchStreamReader implements IPDFStreamReader {
     _headersCapability: import("../shared/util.js").PromiseCapability;
     _disableRange: any;
     _rangeChunkSize: any;
-    _abortController: AbortController | undefined;
+    _abortController: AbortController;
     _isStreamingSupported: boolean;
     _isRangeSupported: boolean;
     _headers: Headers;
@@ -51,7 +51,7 @@ declare class PDFFetchStreamRangeReader implements IPDFStreamRangeReader {
     _withCredentials: any;
     _readCapability: import("../shared/util.js").PromiseCapability;
     _isStreamingSupported: boolean;
-    _abortController: AbortController | undefined;
+    _abortController: AbortController;
     _headers: Headers;
     onProgress: any;
     get isStreamingSupported(): boolean;

+ 1 - 2
types/src/pdf.d.ts

@@ -10,7 +10,6 @@ import { AnnotationEditorType } from "./shared/util.js";
 import { AnnotationEditorUIManager } from "./display/editor/tools.js";
 import { AnnotationLayer } from "./display/annotation_layer.js";
 import { AnnotationMode } from "./shared/util.js";
-import { binarySearchFirstItem } from "./display/display_utils.js";
 import { build } from "./display/api.js";
 import { CMapCompressionType } from "./shared/util.js";
 import { createPromiseCapability } from "./shared/util.js";
@@ -42,4 +41,4 @@ import { Util } from "./shared/util.js";
 import { VerbosityLevel } from "./shared/util.js";
 import { version } from "./display/api.js";
 import { XfaLayer } from "./display/xfa_layer.js";
-export { AnnotationEditorLayer, AnnotationEditorParamsType, AnnotationEditorType, AnnotationEditorUIManager, AnnotationLayer, AnnotationMode, binarySearchFirstItem, build, CMapCompressionType, createPromiseCapability, createValidAbsoluteUrl, getDocument, getFilenameFromUrl, getPdfFilenameFromUrl, getXfaPageViewport, GlobalWorkerOptions, InvalidPDFException, isPdfFile, loadScript, LoopbackPort, MissingPDFException, OPS, PasswordResponses, PDFDataRangeTransport, PDFDateString, PDFWorker, PermissionFlag, PixelsPerInch, RenderingCancelledException, renderTextLayer, shadow, SVGGraphics, UnexpectedResponseException, UNSUPPORTED_FEATURES, Util, VerbosityLevel, version, XfaLayer };
+export { AnnotationEditorLayer, AnnotationEditorParamsType, AnnotationEditorType, AnnotationEditorUIManager, AnnotationLayer, AnnotationMode, build, CMapCompressionType, createPromiseCapability, createValidAbsoluteUrl, getDocument, getFilenameFromUrl, getPdfFilenameFromUrl, getXfaPageViewport, GlobalWorkerOptions, InvalidPDFException, isPdfFile, loadScript, LoopbackPort, MissingPDFException, OPS, PasswordResponses, PDFDataRangeTransport, PDFDateString, PDFWorker, PermissionFlag, PixelsPerInch, RenderingCancelledException, renderTextLayer, shadow, SVGGraphics, UnexpectedResponseException, UNSUPPORTED_FEATURES, Util, VerbosityLevel, version, XfaLayer };

+ 4 - 0
types/web/annotation_editor_layer_builder.d.ts

@@ -3,6 +3,7 @@ export type PageViewport = import("../src/display/display_utils").PageViewport;
 export type IPDFLinkService = import("./interfaces").IPDFLinkService;
 export type AnnotationEditorUIManager = import("../src/display/editor/tools.js").AnnotationEditorUIManager;
 export type AnnotationStorage = any;
+export type TextAccessibilityManager = import("./text_accessibility.js").TextAccessibilityManager;
 export type IL10n = import("./interfaces").IL10n;
 export type AnnotationEditorLayerBuilderOptions = {
     /**
@@ -11,6 +12,7 @@ export type AnnotationEditorLayerBuilderOptions = {
     mode: number;
     pageDiv: HTMLDivElement;
     pdfPage: PDFPageProxy;
+    accessibilityManager: TextAccessibilityManager;
     annotationStorage: any;
     /**
      * - Localization service.
@@ -23,6 +25,7 @@ export type AnnotationEditorLayerBuilderOptions = {
  * @property {number} mode - Editor mode
  * @property {HTMLDivElement} pageDiv
  * @property {PDFPageProxy} pdfPage
+ * @property {TextAccessibilityManager} accessibilityManager
  * @property {AnnotationStorage} annotationStorage
  * @property {IL10n} l10n - Localization service.
  * @property {AnnotationEditorUIManager} uiManager
@@ -35,6 +38,7 @@ export class AnnotationEditorLayerBuilder {
     pageDiv: HTMLDivElement;
     pdfPage: import("../src/display/api").PDFPageProxy;
     annotationStorage: any;
+    accessibilityManager: import("./text_accessibility.js").TextAccessibilityManager;
     l10n: import("./interfaces").IL10n;
     annotationEditorLayer: any;
     div: HTMLDivElement | null;

+ 5 - 1
types/web/annotation_layer_builder.d.ts

@@ -3,6 +3,7 @@ export type PageViewport = import("../src/display/display_utils").PageViewport;
 export type IDownloadManager = import("./interfaces").IDownloadManager;
 export type IL10n = import("./interfaces").IL10n;
 export type IPDFLinkService = import("./interfaces").IPDFLinkService;
+export type TextAccessibilityManager = any;
 export type AnnotationLayerBuilderOptions = {
     pageDiv: HTMLDivElement;
     pdfPage: PDFPageProxy;
@@ -26,6 +27,7 @@ export type AnnotationLayerBuilderOptions = {
     } | null> | undefined;
     mouseState?: Object | undefined;
     annotationCanvasMap?: Map<string, HTMLCanvasElement> | undefined;
+    accessibilityManager: any;
 };
 /**
  * @typedef {Object} AnnotationLayerBuilderOptions
@@ -44,12 +46,13 @@ export type AnnotationLayerBuilderOptions = {
  *   [fieldObjectsPromise]
  * @property {Object} [mouseState]
  * @property {Map<string, HTMLCanvasElement>} [annotationCanvasMap]
+ * @property {TextAccessibilityManager} accessibilityManager
  */
 export class AnnotationLayerBuilder {
     /**
      * @param {AnnotationLayerBuilderOptions} options
      */
-    constructor({ pageDiv, pdfPage, linkService, downloadManager, annotationStorage, imageResourcesPath, renderForms, l10n, enableScripting, hasJSActionsPromise, fieldObjectsPromise, mouseState, annotationCanvasMap, }: AnnotationLayerBuilderOptions);
+    constructor({ pageDiv, pdfPage, linkService, downloadManager, annotationStorage, imageResourcesPath, renderForms, l10n, enableScripting, hasJSActionsPromise, fieldObjectsPromise, mouseState, annotationCanvasMap, accessibilityManager, }: AnnotationLayerBuilderOptions);
     pageDiv: HTMLDivElement;
     pdfPage: import("../src/display/api").PDFPageProxy;
     linkService: import("./interfaces").IPDFLinkService;
@@ -65,6 +68,7 @@ export class AnnotationLayerBuilder {
     } | null>;
     _mouseState: Object;
     _annotationCanvasMap: Map<string, HTMLCanvasElement>;
+    _accessibilityManager: any;
     div: HTMLDivElement | null;
     _cancelled: boolean;
     /**

+ 14 - 4
types/web/base_viewer.d.ts

@@ -10,6 +10,7 @@ export type IPDFLinkService = import("./interfaces").IPDFLinkService;
 export type IPDFStructTreeLayerFactory = import("./interfaces").IPDFStructTreeLayerFactory;
 export type IPDFTextLayerFactory = import("./interfaces").IPDFTextLayerFactory;
 export type IPDFXfaLayerFactory = import("./interfaces").IPDFXfaLayerFactory;
+export type TextAccessibilityManager = import("./text_accessibility.js").TextAccessibilityManager;
 export type PDFViewerOptions = {
     /**
      * - The container for the viewer element.
@@ -325,18 +326,20 @@ export class BaseViewer implements IPDFAnnotationLayerFactory, IPDFAnnotationEdi
      * @property {boolean} [enhanceTextSelection]
      * @property {EventBus} eventBus
      * @property {TextHighlighter} highlighter
+     * @property {TextAccessibilityManager} [accessibilityManager]
      */
     /**
      * @param {CreateTextLayerBuilderParameters}
      * @returns {TextLayerBuilder}
      */
-    createTextLayerBuilder({ textLayerDiv, pageIndex, viewport, enhanceTextSelection, eventBus, highlighter, }: {
+    createTextLayerBuilder({ textLayerDiv, pageIndex, viewport, enhanceTextSelection, eventBus, highlighter, accessibilityManager, }: {
         textLayerDiv: HTMLDivElement;
         pageIndex: number;
         viewport: PageViewport;
         enhanceTextSelection?: boolean | undefined;
         eventBus: EventBus;
         highlighter: TextHighlighter;
+        accessibilityManager?: import("./text_accessibility.js").TextAccessibilityManager | undefined;
     }): TextLayerBuilder;
     /**
      * @typedef {Object} CreateTextHighlighterParameters
@@ -368,12 +371,13 @@ export class BaseViewer implements IPDFAnnotationLayerFactory, IPDFAnnotationEdi
      *   [fieldObjectsPromise]
      * @property {Map<string, HTMLCanvasElement>} [annotationCanvasMap] - Map some
      *   annotation ids with canvases used to render them.
+     * @property {TextAccessibilityManager} [accessibilityManager]
      */
     /**
      * @param {CreateAnnotationLayerBuilderParameters}
      * @returns {AnnotationLayerBuilder}
      */
-    createAnnotationLayerBuilder({ pageDiv, pdfPage, annotationStorage, imageResourcesPath, renderForms, l10n, enableScripting, hasJSActionsPromise, mouseState, fieldObjectsPromise, annotationCanvasMap, }: {
+    createAnnotationLayerBuilder({ pageDiv, pdfPage, annotationStorage, imageResourcesPath, renderForms, l10n, enableScripting, hasJSActionsPromise, mouseState, fieldObjectsPromise, annotationCanvasMap, accessibilityManager, }: {
         pageDiv: HTMLDivElement;
         pdfPage: PDFPageProxy;
         /**
@@ -399,6 +403,7 @@ export class BaseViewer implements IPDFAnnotationLayerFactory, IPDFAnnotationEdi
          * annotation ids with canvases used to render them.
          */
         annotationCanvasMap?: Map<string, HTMLCanvasElement> | undefined;
+        accessibilityManager?: import("./text_accessibility.js").TextAccessibilityManager | undefined;
     }): AnnotationLayerBuilder;
     /**
      * @typedef {Object} CreateAnnotationEditorLayerBuilderParameters
@@ -407,22 +412,26 @@ export class BaseViewer implements IPDFAnnotationLayerFactory, IPDFAnnotationEdi
      * @property {PDFPageProxy} pdfPage
      * @property {IL10n} l10n
      * @property {AnnotationStorage} [annotationStorage] - Storage for annotation
+     * @property {TextAccessibilityManager} [accessibilityManager]
      *   data in forms.
      */
     /**
      * @param {CreateAnnotationEditorLayerBuilderParameters}
      * @returns {AnnotationEditorLayerBuilder}
      */
-    createAnnotationEditorLayerBuilder({ uiManager, pageDiv, pdfPage, l10n, annotationStorage, }: {
+    createAnnotationEditorLayerBuilder({ uiManager, pageDiv, pdfPage, accessibilityManager, l10n, annotationStorage, }: {
         uiManager?: any;
         pageDiv: HTMLDivElement;
         pdfPage: PDFPageProxy;
         l10n: IL10n;
         /**
          * - Storage for annotation
-         * data in forms.
          */
         annotationStorage?: any;
+        /**
+         * data in forms.
+         */
+        accessibilityManager?: import("./text_accessibility.js").TextAccessibilityManager | undefined;
     }): AnnotationEditorLayerBuilder;
     /**
      * @typedef {Object} CreateXfaLayerBuilderParameters
@@ -530,6 +539,7 @@ export class BaseViewer implements IPDFAnnotationLayerFactory, IPDFAnnotationEdi
      */
     get annotationEditorMode(): number;
     set annotationEditorParams(arg: any);
+    refresh(): void;
     #private;
 }
 export namespace PagesCountLimit {

+ 13 - 4
types/web/default_factory.d.ts

@@ -10,6 +10,7 @@ export type IPDFStructTreeLayerFactory = import("./interfaces").IPDFStructTreeLa
 export type IPDFTextLayerFactory = import("./interfaces").IPDFTextLayerFactory;
 export type IPDFXfaLayerFactory = import("./interfaces").IPDFXfaLayerFactory;
 export type TextHighlighter = import("./text_highlighter").TextHighlighter;
+export type TextAccessibilityManager = import("./text_accessibility.js").TextAccessibilityManager;
 /**
  * @implements IPDFAnnotationEditorLayerFactory
  */
@@ -21,22 +22,26 @@ export class DefaultAnnotationEditorLayerFactory implements IPDFAnnotationEditor
      * @property {PDFPageProxy} pdfPage
      * @property {IL10n} l10n
      * @property {AnnotationStorage} [annotationStorage] - Storage for annotation
+     * @property {TextAccessibilityManager} [accessibilityManager]
      *   data in forms.
      */
     /**
      * @param {CreateAnnotationEditorLayerBuilderParameters}
      * @returns {AnnotationEditorLayerBuilder}
      */
-    createAnnotationEditorLayerBuilder({ uiManager, pageDiv, pdfPage, l10n, annotationStorage, }: {
+    createAnnotationEditorLayerBuilder({ uiManager, pageDiv, pdfPage, accessibilityManager, l10n, annotationStorage, }: {
         uiManager?: any;
         pageDiv: HTMLDivElement;
         pdfPage: PDFPageProxy;
         l10n: IL10n;
         /**
          * - Storage for annotation
-         * data in forms.
          */
         annotationStorage?: any;
+        /**
+         * data in forms.
+         */
+        accessibilityManager?: import("./text_accessibility.js").TextAccessibilityManager | undefined;
     }): AnnotationEditorLayerBuilder;
 }
 /**
@@ -60,12 +65,13 @@ export class DefaultAnnotationLayerFactory implements IPDFAnnotationLayerFactory
      *   [fieldObjectsPromise]
      * @property {Map<string, HTMLCanvasElement>} [annotationCanvasMap] - Map some
      *   annotation ids with canvases used to render them.
+     * @property {TextAccessibilityManager} [accessibilityManager]
      */
     /**
      * @param {CreateAnnotationLayerBuilderParameters}
      * @returns {AnnotationLayerBuilder}
      */
-    createAnnotationLayerBuilder({ pageDiv, pdfPage, annotationStorage, imageResourcesPath, renderForms, l10n, enableScripting, hasJSActionsPromise, mouseState, fieldObjectsPromise, annotationCanvasMap, }: {
+    createAnnotationLayerBuilder({ pageDiv, pdfPage, annotationStorage, imageResourcesPath, renderForms, l10n, enableScripting, hasJSActionsPromise, mouseState, fieldObjectsPromise, annotationCanvasMap, accessibilityManager, }: {
         pageDiv: HTMLDivElement;
         pdfPage: PDFPageProxy;
         /**
@@ -91,6 +97,7 @@ export class DefaultAnnotationLayerFactory implements IPDFAnnotationLayerFactory
          * annotation ids with canvases used to render them.
          */
         annotationCanvasMap?: Map<string, HTMLCanvasElement> | undefined;
+        accessibilityManager?: import("./text_accessibility.js").TextAccessibilityManager | undefined;
     }): AnnotationLayerBuilder;
 }
 /**
@@ -121,18 +128,20 @@ export class DefaultTextLayerFactory implements IPDFTextLayerFactory {
      * @property {boolean} [enhanceTextSelection]
      * @property {EventBus} eventBus
      * @property {TextHighlighter} highlighter
+     * @property {TextAccessibilityManager} [accessibilityManager]
      */
     /**
      * @param {CreateTextLayerBuilderParameters}
      * @returns {TextLayerBuilder}
      */
-    createTextLayerBuilder({ textLayerDiv, pageIndex, viewport, enhanceTextSelection, eventBus, highlighter, }: {
+    createTextLayerBuilder({ textLayerDiv, pageIndex, viewport, enhanceTextSelection, eventBus, highlighter, accessibilityManager, }: {
         textLayerDiv: HTMLDivElement;
         pageIndex: number;
         viewport: PageViewport;
         enhanceTextSelection?: boolean | undefined;
         eventBus: EventBus;
         highlighter: TextHighlighter;
+        accessibilityManager?: import("./text_accessibility.js").TextAccessibilityManager | undefined;
     }): TextLayerBuilder;
 }
 /**

+ 14 - 4
types/web/interfaces.d.ts

@@ -8,6 +8,7 @@ export type TextHighlighter = import("./text_highlighter").TextHighlighter;
 export type TextLayerBuilder = import("./text_layer_builder").TextLayerBuilder;
 export type RenderingStates = any;
 export type XfaLayerBuilder = import("./xfa_layer_builder").XfaLayerBuilder;
+export type TextAccessibilityManager = import("./text_accessibility.js").TextAccessibilityManager;
 /**
  * @interface
  */
@@ -77,22 +78,26 @@ export class IPDFAnnotationEditorLayerFactory {
      * @property {PDFPageProxy} pdfPage
      * @property {IL10n} l10n
      * @property {AnnotationStorage} [annotationStorage] - Storage for annotation
+     * @property {TextAccessibilityManager} [accessibilityManager]
      *   data in forms.
      */
     /**
      * @param {CreateAnnotationEditorLayerBuilderParameters}
      * @returns {AnnotationEditorLayerBuilder}
      */
-    createAnnotationEditorLayerBuilder({ uiManager, pageDiv, pdfPage, l10n, annotationStorage, }: {
+    createAnnotationEditorLayerBuilder({ uiManager, pageDiv, pdfPage, l10n, annotationStorage, accessibilityManager, }: {
         uiManager?: any;
         pageDiv: HTMLDivElement;
         pdfPage: PDFPageProxy;
         l10n: IL10n;
         /**
          * - Storage for annotation
-         * data in forms.
          */
         annotationStorage?: any;
+        /**
+         * data in forms.
+         */
+        accessibilityManager?: import("./text_accessibility.js").TextAccessibilityManager | undefined;
     }): AnnotationEditorLayerBuilder;
 }
 /**
@@ -116,12 +121,13 @@ export class IPDFAnnotationLayerFactory {
      *   [fieldObjectsPromise]
      * @property {Map<string, HTMLCanvasElement>} [annotationCanvasMap] - Map some
      *   annotation ids with canvases used to render them.
+     * @property {TextAccessibilityManager} [accessibilityManager]
      */
     /**
      * @param {CreateAnnotationLayerBuilderParameters}
      * @returns {AnnotationLayerBuilder}
      */
-    createAnnotationLayerBuilder({ pageDiv, pdfPage, annotationStorage, imageResourcesPath, renderForms, l10n, enableScripting, hasJSActionsPromise, mouseState, fieldObjectsPromise, annotationCanvasMap, }: {
+    createAnnotationLayerBuilder({ pageDiv, pdfPage, annotationStorage, imageResourcesPath, renderForms, l10n, enableScripting, hasJSActionsPromise, mouseState, fieldObjectsPromise, annotationCanvasMap, accessibilityManager, }: {
         pageDiv: HTMLDivElement;
         pdfPage: PDFPageProxy;
         /**
@@ -147,6 +153,7 @@ export class IPDFAnnotationLayerFactory {
          * annotation ids with canvases used to render them.
          */
         annotationCanvasMap?: Map<string, HTMLCanvasElement> | undefined;
+        accessibilityManager?: import("./text_accessibility.js").TextAccessibilityManager | undefined;
     }): AnnotationLayerBuilder;
 }
 /** @typedef {import("../src/display/api").PDFPageProxy} PDFPageProxy */
@@ -159,6 +166,7 @@ export class IPDFAnnotationLayerFactory {
 /** @typedef {import("./text_layer_builder").TextLayerBuilder} TextLayerBuilder */
 /** @typedef {import("./ui_utils").RenderingStates} RenderingStates */
 /** @typedef {import("./xfa_layer_builder").XfaLayerBuilder} XfaLayerBuilder */
+/** @typedef {import("./text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */
 /**
  * @interface
  */
@@ -265,18 +273,20 @@ export class IPDFTextLayerFactory {
      * @property {boolean} [enhanceTextSelection]
      * @property {EventBus} eventBus
      * @property {TextHighlighter} highlighter
+     * @property {TextAccessibilityManager} [accessibilityManager]
      */
     /**
      * @param {CreateTextLayerBuilderParameters}
      * @returns {TextLayerBuilder}
      */
-    createTextLayerBuilder({ textLayerDiv, pageIndex, viewport, enhanceTextSelection, eventBus, highlighter, }: {
+    createTextLayerBuilder({ textLayerDiv, pageIndex, viewport, enhanceTextSelection, eventBus, highlighter, accessibilityManager, }: {
         textLayerDiv: HTMLDivElement;
         pageIndex: number;
         viewport: PageViewport;
         enhanceTextSelection?: boolean | undefined;
         eventBus: EventBus;
         highlighter: TextHighlighter;
+        accessibilityManager?: import("./text_accessibility.js").TextAccessibilityManager | undefined;
     }): TextLayerBuilder;
 }
 /**

+ 1 - 1
types/web/pdf_link_service.d.ts

@@ -75,7 +75,7 @@ export namespace LinkTarget {
  * @implements {IPDFLinkService}
  */
 export class PDFLinkService implements IPDFLinkService {
-    static "__#26@#isValidExplicitDestination"(dest: any): boolean;
+    static "__#27@#isValidExplicitDestination"(dest: any): boolean;
     /**
      * @param {PDFLinkServiceOptions} options
      */

+ 21 - 16
types/web/pdf_page_view.d.ts

@@ -25,7 +25,7 @@ export type PDFPageViewOptions = {
     /**
      * - The page scale display.
      */
-    scale: number;
+    scale?: number | undefined;
     /**
      * - The page viewport.
      */
@@ -39,8 +39,8 @@ export type PDFPageViewOptions = {
     /**
      * - The rendering queue object.
      */
-    renderingQueue: PDFRenderingQueue;
-    textLayerFactory: IPDFTextLayerFactory;
+    renderingQueue?: import("./pdf_rendering_queue").PDFRenderingQueue | undefined;
+    textLayerFactory?: import("./interfaces").IPDFTextLayerFactory | undefined;
     /**
      * - Controls if the text layer used for
      * selection and searching is created, and if the improved text selection
@@ -56,10 +56,10 @@ export type PDFPageViewOptions = {
      * The default value is `AnnotationMode.ENABLE_FORMS`.
      */
     annotationMode?: number | undefined;
-    annotationLayerFactory: IPDFAnnotationLayerFactory;
-    annotationEditorLayerFactory: IPDFAnnotationEditorLayerFactory;
-    xfaLayerFactory: IPDFXfaLayerFactory;
-    structTreeLayerFactory: IPDFStructTreeLayerFactory;
+    annotationLayerFactory?: import("./interfaces").IPDFAnnotationLayerFactory | undefined;
+    annotationEditorLayerFactory?: import("./interfaces").IPDFAnnotationEditorLayerFactory | undefined;
+    xfaLayerFactory?: import("./interfaces").IPDFXfaLayerFactory | undefined;
+    structTreeLayerFactory?: import("./interfaces").IPDFStructTreeLayerFactory | undefined;
     textHighlighterFactory?: Object | undefined;
     /**
      * - Path for image resources, mainly
@@ -86,7 +86,7 @@ export type PDFPageViewOptions = {
     /**
      * - Localization service.
      */
-    l10n: IL10n;
+    l10n?: import("./interfaces").IL10n | undefined;
 };
 /**
  * @implements {IRenderableView}
@@ -112,15 +112,20 @@ export class PDFPageView implements IRenderableView {
     maxCanvasPixels: any;
     pageColors: Object | null;
     eventBus: import("./event_utils").EventBus;
-    renderingQueue: import("./pdf_rendering_queue").PDFRenderingQueue;
-    textLayerFactory: import("./interfaces").IPDFTextLayerFactory;
-    annotationLayerFactory: import("./interfaces").IPDFAnnotationLayerFactory;
-    annotationEditorLayerFactory: import("./interfaces").IPDFAnnotationEditorLayerFactory;
-    xfaLayerFactory: import("./interfaces").IPDFXfaLayerFactory;
+    renderingQueue: import("./pdf_rendering_queue").PDFRenderingQueue | undefined;
+    textLayerFactory: import("./interfaces").IPDFTextLayerFactory | undefined;
+    annotationLayerFactory: import("./interfaces").IPDFAnnotationLayerFactory | undefined;
+    annotationEditorLayerFactory: import("./interfaces").IPDFAnnotationEditorLayerFactory | undefined;
+    xfaLayerFactory: import("./interfaces").IPDFXfaLayerFactory | undefined;
     textHighlighter: any;
-    structTreeLayerFactory: import("./interfaces").IPDFStructTreeLayerFactory;
+    structTreeLayerFactory: import("./interfaces").IPDFStructTreeLayerFactory | undefined;
     renderer: any;
-    l10n: import("./interfaces").IL10n;
+    l10n: {
+        getLanguage(): Promise<string>;
+        getDirection(): Promise<string>;
+        get(key: any, args?: null, fallback?: any): Promise<any>;
+        translate(element: any): Promise<void>;
+    };
     paintTask: {
         promise: any;
         onRenderContinue(cont: any): void;
@@ -137,7 +142,7 @@ export class PDFPageView implements IRenderableView {
     annotationEditorLayer: any;
     textLayer: import("./text_layer_builder.js").TextLayerBuilder | null;
     zoomLayer: ParentNode | null;
-    xfaLayer: import("./xfa_layer_builder.js").XfaLayerBuilder | null;
+    xfaLayer: any;
     structTreeLayer: any;
     div: HTMLDivElement;
     setPdfPage(pdfPage: any): void;

+ 1 - 1
types/web/pdf_thumbnail_view.d.ts

@@ -117,7 +117,7 @@ export class PDFThumbnailView implements IRenderableView {
  *   mode.
  */
 export class TempImageFactory {
-    static "__#27@#tempCanvas": null;
+    static "__#28@#tempCanvas": null;
     static getCanvas(width: any, height: any): (HTMLCanvasElement | CanvasRenderingContext2D | null)[];
     static destroyCanvas(): void;
 }

+ 4 - 1
types/web/pdf_viewer.component.d.ts

@@ -17,8 +17,11 @@ import { PDFScriptingManager } from "./pdf_scripting_manager.js";
 import { PDFSinglePageViewer } from "./pdf_viewer.js";
 import { PDFViewer } from "./pdf_viewer.js";
 import { ProgressBar } from "./ui_utils.js";
+import { RenderingStates } from "./ui_utils.js";
+import { ScrollMode } from "./ui_utils.js";
 import { SimpleLinkService } from "./pdf_link_service.js";
+import { SpreadMode } from "./ui_utils.js";
 import { StructTreeLayerBuilder } from "./struct_tree_layer_builder.js";
 import { TextLayerBuilder } from "./text_layer_builder.js";
 import { XfaLayerBuilder } from "./xfa_layer_builder.js";
-export { AnnotationLayerBuilder, DefaultAnnotationLayerFactory, DefaultStructTreeLayerFactory, DefaultTextLayerFactory, DefaultXfaLayerFactory, DownloadManager, EventBus, GenericL10n, LinkTarget, NullL10n, parseQueryString, PDFFindController, PDFHistory, PDFLinkService, PDFPageView, PDFScriptingManager, PDFSinglePageViewer, PDFViewer, ProgressBar, SimpleLinkService, StructTreeLayerBuilder, TextLayerBuilder, XfaLayerBuilder };
+export { AnnotationLayerBuilder, DefaultAnnotationLayerFactory, DefaultStructTreeLayerFactory, DefaultTextLayerFactory, DefaultXfaLayerFactory, DownloadManager, EventBus, GenericL10n, LinkTarget, NullL10n, parseQueryString, PDFFindController, PDFHistory, PDFLinkService, PDFPageView, PDFScriptingManager, PDFSinglePageViewer, PDFViewer, ProgressBar, RenderingStates, ScrollMode, SimpleLinkService, SpreadMode, StructTreeLayerBuilder, TextLayerBuilder, XfaLayerBuilder };

+ 42 - 0
types/web/text_accessibility.d.ts

@@ -0,0 +1,42 @@
+/**
+ * This class aims to provide some methods:
+ *  - to reorder elements in the DOM with respect to the visual order;
+ *  - to create a link, using aria-owns, between spans in the textLayer and
+ *    annotations in the annotationLayer. The goal is to help to know
+ *    where the annotations are in the text flow.
+ */
+export class TextAccessibilityManager {
+    /**
+     * Compare the positions of two elements, it must correspond to
+     * the visual ordering.
+     *
+     * @param {HTMLElement} e1
+     * @param {HTMLElement} e2
+     * @returns {number}
+     */
+    static "__#23@#compareElementPositions"(e1: HTMLElement, e2: HTMLElement): number;
+    setTextMapping(textDivs: any): void;
+    /**
+     * Function called when the text layer has finished rendering.
+     */
+    enable(): void;
+    disable(): void;
+    /**
+     * Remove an aria-owns id from a node in the text layer.
+     * @param {HTMLElement} element
+     */
+    removePointerInTextLayer(element: HTMLElement): void;
+    /**
+     * Find the text node which is the nearest and add an aria-owns attribute
+     * in order to correctly position this editor in the text flow.
+     * @param {HTMLElement} element
+     * @param {boolean} isRemovable
+     */
+    addPointerInTextLayer(element: HTMLElement, isRemovable: boolean): void;
+    /**
+     * Move a div in the DOM in order to respect the visual order.
+     * @param {HTMLDivElement} element
+     */
+    moveElementInDOM(container: any, element: HTMLDivElement, contentElement: any, isRemovable: any): void;
+    #private;
+}

部分文件因文件數量過多而無法顯示