Pārlūkot izejas kodu

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

pdfjsbot 4 gadi atpakaļ
vecāks
revīzija
75158b4de0
100 mainītis faili ar 7803 papildinājumiem un 4369 dzēšanām
  1. 1 1
      README.md
  2. 1 1
      bower.json
  3. 242 433
      build/pdf.js
  4. 0 0
      build/pdf.js.map
  5. 1 1
      build/pdf.min.js
  6. 39 0
      build/pdf.sandbox.js
  7. 0 0
      build/pdf.sandbox.js.map
  8. 21 0
      build/pdf.sandbox.min.js
  9. 1 1
      build/pdf.worker.entry.js
  10. 381 218
      build/pdf.worker.js
  11. 0 0
      build/pdf.worker.js.map
  12. 1 1
      build/pdf.worker.min.js
  13. 0 0
      es5/build/pdf.js.map
  14. 0 21
      es5/build/pdf.min.js
  15. 0 0
      es5/build/pdf.worker.js.map
  16. 0 21
      es5/build/pdf.worker.min.js
  17. 0 0
      es5/image_decoders/pdf.image_decoders.js.map
  18. 0 21
      es5/image_decoders/pdf.image_decoders.min.js
  19. 0 0
      es5/web/pdf_viewer.js.map
  20. 185 169
      image_decoders/pdf.image_decoders.js
  21. 0 0
      image_decoders/pdf.image_decoders.js.map
  22. 1 1
      image_decoders/pdf.image_decoders.min.js
  23. 0 0
      legacy/build/pdf.d.ts
  24. 224 407
      legacy/build/pdf.js
  25. 0 0
      legacy/build/pdf.js.map
  26. 21 0
      legacy/build/pdf.min.js
  27. 39 0
      legacy/build/pdf.sandbox.js
  28. 0 0
      legacy/build/pdf.sandbox.js.map
  29. 21 0
      legacy/build/pdf.sandbox.min.js
  30. 1 1
      legacy/build/pdf.worker.entry.js
  31. 230 225
      legacy/build/pdf.worker.js
  32. 0 0
      legacy/build/pdf.worker.js.map
  33. 21 0
      legacy/build/pdf.worker.min.js
  34. 212 253
      legacy/image_decoders/pdf.image_decoders.js
  35. 0 0
      legacy/image_decoders/pdf.image_decoders.js.map
  36. 21 0
      legacy/image_decoders/pdf.image_decoders.min.js
  37. 0 0
      legacy/web/images/annotation-check.svg
  38. 0 0
      legacy/web/images/annotation-comment.svg
  39. 0 0
      legacy/web/images/annotation-help.svg
  40. 0 0
      legacy/web/images/annotation-insert.svg
  41. 0 0
      legacy/web/images/annotation-key.svg
  42. 0 0
      legacy/web/images/annotation-newparagraph.svg
  43. 0 0
      legacy/web/images/annotation-noicon.svg
  44. 0 0
      legacy/web/images/annotation-note.svg
  45. 0 0
      legacy/web/images/annotation-paragraph.svg
  46. 0 0
      legacy/web/images/loading-icon.gif
  47. 0 0
      legacy/web/images/shadow.png
  48. 178 6
      legacy/web/pdf_viewer.css
  49. 1046 1296
      legacy/web/pdf_viewer.js
  50. 0 0
      legacy/web/pdf_viewer.js.map
  51. 316 126
      lib/core/annotation.js
  52. 1 1
      lib/core/arithmetic_decoder.js
  53. 1 1
      lib/core/bidi.js
  54. 1 1
      lib/core/ccitt.js
  55. 2 2
      lib/core/ccitt_stream.js
  56. 1 2
      lib/core/cff_parser.js
  57. 1 1
      lib/core/charsets.js
  58. 1 1
      lib/core/chunked_stream.js
  59. 65 75
      lib/core/cmap.js
  60. 2 2
      lib/core/colorspace.js
  61. 83 21
      lib/core/core_utils.js
  62. 122 110
      lib/core/crypto.js
  63. 8 8
      lib/core/default_appearance.js
  64. 125 5
      lib/core/document.js
  65. 1 1
      lib/core/encodings.js
  66. 47 43
      lib/core/evaluator.js
  67. 59 59
      lib/core/font_renderer.js
  68. 15 8
      lib/core/fonts.js
  69. 366 353
      lib/core/function.js
  70. 2 2
      lib/core/glyphlist.js
  71. 1 1
      lib/core/image.js
  72. 50 8
      lib/core/image_utils.js
  73. 1 1
      lib/core/jbig2.js
  74. 1 1
      lib/core/jbig2_stream.js
  75. 1 1
      lib/core/jpeg_stream.js
  76. 1 1
      lib/core/jpg.js
  77. 1 1
      lib/core/jpx.js
  78. 1 1
      lib/core/jpx_stream.js
  79. 155 0
      lib/core/metadata_parser.js
  80. 2 2
      lib/core/metrics.js
  81. 1 1
      lib/core/murmurhash3.js
  82. 36 15
      lib/core/obj.js
  83. 121 122
      lib/core/operator_list.js
  84. 1 1
      lib/core/parser.js
  85. 142 149
      lib/core/pattern.js
  86. 22 18
      lib/core/pdf_manager.js
  87. 10 10
      lib/core/primitives.js
  88. 1 1
      lib/core/ps_parser.js
  89. 1 1
      lib/core/standard_fonts.js
  90. 10 4
      lib/core/stream.js
  91. 119 108
      lib/core/type1_parser.js
  92. 10 10
      lib/core/unicode.js
  93. 21 10
      lib/core/worker.js
  94. 1 1
      lib/core/worker_stream.js
  95. 2 2
      lib/core/writer.js
  96. 535 0
      lib/core/xfa/bind.js
  97. 232 0
      lib/core/xfa/builder.js
  98. 1905 0
      lib/core/xfa/config.js
  99. 230 0
      lib/core/xfa/connection_set.js
  100. 82 0
      lib/core/xfa/datasets.js

+ 1 - 1
README.md

@@ -9,6 +9,6 @@ generated by the build scripts.
 
 For usage with older browsers or environments, without support for modern
 features such as e.g. `async`/`await`, `ReadableStream`, optional chaining, and
-nullish coalescing; please see the `es5` folder.
+nullish coalescing; 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.7.570",
+  "version": "2.8.335",
   "main": [
     "build/pdf.js",
     "build/pdf.worker.js"

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 242 - 433
build/pdf.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
build/pdf.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
build/pdf.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 39 - 0
build/pdf.sandbox.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
build/pdf.sandbox.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 21 - 0
build/pdf.sandbox.min.js


+ 1 - 1
build/pdf.worker.entry.js

@@ -1,4 +1,4 @@
-/* Copyright 2020 Mozilla Foundation
+/* Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 381 - 218
build/pdf.worker.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
build/pdf.worker.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
build/pdf.worker.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
es5/build/pdf.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 21
es5/build/pdf.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
es5/build/pdf.worker.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 21
es5/build/pdf.worker.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
es5/image_decoders/pdf.image_decoders.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 21
es5/image_decoders/pdf.image_decoders.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
es5/web/pdf_viewer.js.map


+ 185 - 169
image_decoders/pdf.image_decoders.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,57 +33,7 @@
 return /******/ (() => { // webpackBootstrap
 /******/ 	"use strict";
 /******/ 	var __webpack_modules__ = ([
-/* 0 */
-/***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
-
-
-
-Object.defineProperty(exports, "__esModule", ({
-  value: true
-}));
-Object.defineProperty(exports, "getVerbosityLevel", ({
-  enumerable: true,
-  get: function () {
-    return _util.getVerbosityLevel;
-  }
-}));
-Object.defineProperty(exports, "setVerbosityLevel", ({
-  enumerable: true,
-  get: function () {
-    return _util.setVerbosityLevel;
-  }
-}));
-Object.defineProperty(exports, "Jbig2mage", ({
-  enumerable: true,
-  get: function () {
-    return _jbig.Jbig2mage;
-  }
-}));
-Object.defineProperty(exports, "JpegImage", ({
-  enumerable: true,
-  get: function () {
-    return _jpg.JpegImage;
-  }
-}));
-Object.defineProperty(exports, "JpxImage", ({
-  enumerable: true,
-  get: function () {
-    return _jpx.JpxImage;
-  }
-}));
-
-var _util = __w_pdfjs_require__(1);
-
-var _jbig = __w_pdfjs_require__(4);
-
-var _jpg = __w_pdfjs_require__(9);
-
-var _jpx = __w_pdfjs_require__(10);
-
-const pdfjsVersion = '2.7.570';
-const pdfjsBuild = 'f2c7338b0';
-
-/***/ }),
+/* 0 */,
 /* 1 */
 /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
 
@@ -96,9 +46,9 @@ exports.arrayByteLength = arrayByteLength;
 exports.arraysToBytes = arraysToBytes;
 exports.assert = assert;
 exports.bytesToString = bytesToString;
+exports.createObjectURL = createObjectURL;
 exports.createPromiseCapability = createPromiseCapability;
 exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
-exports.encodeToXmlString = encodeToXmlString;
 exports.escapeString = escapeString;
 exports.getModificationDate = getModificationDate;
 exports.getVerbosityLevel = getVerbosityLevel;
@@ -110,7 +60,7 @@ exports.isBool = isBool;
 exports.isNum = isNum;
 exports.isSameOrigin = isSameOrigin;
 exports.isString = isString;
-exports.objectFromEntries = objectFromEntries;
+exports.objectFromMap = objectFromMap;
 exports.objectSize = objectSize;
 exports.removeNullCharacters = removeNullCharacters;
 exports.setVerbosityLevel = setVerbosityLevel;
@@ -123,7 +73,7 @@ exports.stringToUTF8String = stringToUTF8String;
 exports.unreachable = unreachable;
 exports.utf8StringToString = utf8StringToString;
 exports.warn = warn;
-exports.VerbosityLevel = exports.Util = exports.UNSUPPORTED_FEATURES = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.IsLittleEndianCached = exports.IsEvalSupportedCached = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.createObjectURL = exports.CMapCompressionType = exports.BaseException = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;
+exports.VerbosityLevel = exports.Util = exports.UNSUPPORTED_FEATURES = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.TextRenderingMode = exports.StreamType = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.IsLittleEndianCached = exports.IsEvalSupportedCached = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;
 
 __w_pdfjs_require__(2);
 
@@ -698,8 +648,14 @@ function objectSize(obj) {
   return Object.keys(obj).length;
 }
 
-function objectFromEntries(iterable) {
-  return Object.assign(Object.create(null), Object.fromEntries(iterable));
+function objectFromMap(map) {
+  const obj = Object.create(null);
+
+  for (const [key, value] of map) {
+    obj[key] = value;
+  }
+
+  return obj;
 }
 
 function isLittleEndian() {
@@ -781,7 +737,7 @@ class Util {
     const c = m[2] * transpose[0] + m[3] * transpose[2];
     const d = m[2] * transpose[1] + m[3] * transpose[3];
     const first = (a + d) / 2;
-    const second = Math.sqrt((a + d) * (a + d) - 4 * (a * d - c * b)) / 2;
+    const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2;
     const sx = first + second || 1;
     const sy = first - second || 1;
     return [Math.sqrt(sx), Math.sqrt(sy)];
@@ -915,9 +871,13 @@ function isArrayEqual(arr1, arr2) {
     return false;
   }
 
-  return arr1.every(function (element, index) {
-    return element === arr2[index];
-  });
+  for (let i = 0, ii = arr1.length; i < ii; i++) {
+    if (arr1[i] !== arr2[i]) {
+      return false;
+    }
+  }
+
+  return true;
 }
 
 function getModificationDate(date = new Date()) {
@@ -948,84 +908,28 @@ function createPromiseCapability() {
   return capability;
 }
 
-const createObjectURL = function createObjectURLClosure() {
-  const digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-  return function createObjectURL(data, contentType, forceDataSchema = false) {
-    if (!forceDataSchema && URL.createObjectURL) {
-      const blob = new Blob([data], {
-        type: contentType
-      });
-      return URL.createObjectURL(blob);
-    }
-
-    let buffer = `data:${contentType};base64,`;
-
-    for (let i = 0, ii = data.length; i < ii; i += 3) {
-      const b1 = data[i] & 0xff;
-      const b2 = data[i + 1] & 0xff;
-      const b3 = data[i + 2] & 0xff;
-      const d1 = b1 >> 2,
-            d2 = (b1 & 3) << 4 | b2 >> 4;
-      const d3 = i + 1 < ii ? (b2 & 0xf) << 2 | b3 >> 6 : 64;
-      const d4 = i + 2 < ii ? b3 & 0x3f : 64;
-      buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
-    }
-
-    return buffer;
-  };
-}();
-
-exports.createObjectURL = createObjectURL;
-const XMLEntities = {
-  0x3c: "&lt;",
-  0x3e: "&gt;",
-  0x26: "&amp;",
-  0x22: "&quot;",
-  0x27: "&apos;"
-};
-
-function encodeToXmlString(str) {
-  const buffer = [];
-  let start = 0;
-
-  for (let i = 0, ii = str.length; i < ii; i++) {
-    const char = str.codePointAt(i);
-
-    if (0x20 <= char && char <= 0x7e) {
-      const entity = XMLEntities[char];
-
-      if (entity) {
-        if (start < i) {
-          buffer.push(str.substring(start, i));
-        }
-
-        buffer.push(entity);
-        start = i + 1;
-      }
-    } else {
-      if (start < i) {
-        buffer.push(str.substring(start, i));
-      }
-
-      buffer.push(`&#x${char.toString(16).toUpperCase()};`);
-
-      if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) {
-        i++;
-      }
-
-      start = i + 1;
-    }
+function createObjectURL(data, contentType = "", forceDataSchema = false) {
+  if (URL.createObjectURL && !forceDataSchema) {
+    return URL.createObjectURL(new Blob([data], {
+      type: contentType
+    }));
   }
 
-  if (buffer.length === 0) {
-    return str;
-  }
+  const digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+  let buffer = `data:${contentType};base64,`;
 
-  if (start < str.length) {
-    buffer.push(str.substring(start, str.length));
+  for (let i = 0, ii = data.length; i < ii; i += 3) {
+    const b1 = data[i] & 0xff;
+    const b2 = data[i + 1] & 0xff;
+    const b3 = data[i + 2] & 0xff;
+    const d1 = b1 >> 2,
+          d2 = (b1 & 3) << 4 | b2 >> 4;
+    const d3 = i + 1 < ii ? (b2 & 0xf) << 2 | b3 >> 6 : 64;
+    const d4 = i + 2 < ii ? b3 & 0x3f : 64;
+    buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4];
   }
 
-  return buffer.join("");
+  return buffer;
 }
 
 /***/ }),
@@ -3268,6 +3172,7 @@ Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
 exports.collectActions = collectActions;
+exports.encodeToXmlString = encodeToXmlString;
 exports.escapePDFName = escapePDFName;
 exports.getArrayLookupTableFactory = getArrayLookupTableFactory;
 exports.getInheritableProperty = getInheritableProperty;
@@ -3342,11 +3247,14 @@ function getInheritableProperty({
   getArray = false,
   stopWhenFound = true
 }) {
-  const LOOP_LIMIT = 100;
-  let loopCount = 0;
   let values;
+  const visited = new _primitives.RefSet();
+
+  while (dict instanceof _primitives.Dict && !(dict.objId && visited.has(dict.objId))) {
+    if (dict.objId) {
+      visited.put(dict.objId);
+    }
 
-  while (dict) {
     const value = getArray ? dict.getArray(key) : dict.get(key);
 
     if (value !== undefined) {
@@ -3361,11 +3269,6 @@ function getInheritableProperty({
       values.push(value);
     }
 
-    if (++loopCount > LOOP_LIMIT) {
-      (0, _util.warn)(`getInheritableProperty: maximum loop count exceeded for "${key}"`);
-      break;
-    }
-
     dict = dict.get("Parent");
   }
 
@@ -3515,25 +3418,36 @@ function _collectJS(entry, xref, list, parents) {
 
 function collectActions(xref, dict, eventType) {
   const actions = Object.create(null);
+  const additionalActionsDicts = getInheritableProperty({
+    dict,
+    key: "AA",
+    stopWhenFound: false
+  });
 
-  if (dict.has("AA")) {
-    const additionalActions = dict.get("AA");
-
-    for (const key of additionalActions.getKeys()) {
-      const action = eventType[key];
+  if (additionalActionsDicts) {
+    for (let i = additionalActionsDicts.length - 1; i >= 0; i--) {
+      const additionalActions = additionalActionsDicts[i];
 
-      if (!action) {
+      if (!(additionalActions instanceof _primitives.Dict)) {
         continue;
       }
 
-      const actionDict = additionalActions.getRaw(key);
-      const parents = new _primitives.RefSet();
-      const list = [];
+      for (const key of additionalActions.getKeys()) {
+        const action = eventType[key];
+
+        if (!action) {
+          continue;
+        }
+
+        const actionDict = additionalActions.getRaw(key);
+        const parents = new _primitives.RefSet();
+        const list = [];
 
-      _collectJS(actionDict, xref, list, parents);
+        _collectJS(actionDict, xref, list, parents);
 
-      if (list.length > 0) {
-        actions[action] = list;
+        if (list.length > 0) {
+          actions[action] = list;
+        }
       }
     }
   }
@@ -3553,6 +3467,58 @@ function collectActions(xref, dict, eventType) {
   return (0, _util.objectSize)(actions) > 0 ? actions : null;
 }
 
+const XMLEntities = {
+  0x3c: "&lt;",
+  0x3e: "&gt;",
+  0x26: "&amp;",
+  0x22: "&quot;",
+  0x27: "&apos;"
+};
+
+function encodeToXmlString(str) {
+  const buffer = [];
+  let start = 0;
+
+  for (let i = 0, ii = str.length; i < ii; i++) {
+    const char = str.codePointAt(i);
+
+    if (0x20 <= char && char <= 0x7e) {
+      const entity = XMLEntities[char];
+
+      if (entity) {
+        if (start < i) {
+          buffer.push(str.substring(start, i));
+        }
+
+        buffer.push(entity);
+        start = i + 1;
+      }
+    } else {
+      if (start < i) {
+        buffer.push(str.substring(start, i));
+      }
+
+      buffer.push(`&#x${char.toString(16).toUpperCase()};`);
+
+      if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) {
+        i++;
+      }
+
+      start = i + 1;
+    }
+  }
+
+  if (buffer.length === 0) {
+    return str;
+  }
+
+  if (start < str.length) {
+    buffer.push(str.substring(start, str.length));
+  }
+
+  return buffer.join("");
+}
+
 /***/ }),
 /* 6 */
 /***/ ((__unused_webpack_module, exports, __w_pdfjs_require__) => {
@@ -3574,10 +3540,10 @@ exports.RefSetCache = exports.RefSet = exports.Ref = exports.Name = exports.EOF
 
 var _util = __w_pdfjs_require__(1);
 
-var EOF = {};
+const EOF = {};
 exports.EOF = EOF;
 
-var Name = function NameClosure() {
+const Name = function NameClosure() {
   let nameCache = Object.create(null);
 
   function Name(name) {
@@ -3587,7 +3553,7 @@ var Name = function NameClosure() {
   Name.prototype = {};
 
   Name.get = function Name_get(name) {
-    var nameValue = nameCache[name];
+    const nameValue = nameCache[name];
     return nameValue ? nameValue : nameCache[name] = new Name(name);
   };
 
@@ -3600,7 +3566,7 @@ var Name = function NameClosure() {
 
 exports.Name = Name;
 
-var Cmd = function CmdClosure() {
+const Cmd = function CmdClosure() {
   let cmdCache = Object.create(null);
 
   function Cmd(cmd) {
@@ -3610,7 +3576,7 @@ var Cmd = function CmdClosure() {
   Cmd.prototype = {};
 
   Cmd.get = function Cmd_get(cmd) {
-    var cmdValue = cmdCache[cmd];
+    const cmdValue = cmdCache[cmd];
     return cmdValue ? cmdValue : cmdCache[cmd] = new Cmd(cmd);
   };
 
@@ -3623,8 +3589,8 @@ var Cmd = function CmdClosure() {
 
 exports.Cmd = Cmd;
 
-var Dict = function DictClosure() {
-  var nonSerializable = function nonSerializableClosure() {
+const Dict = function DictClosure() {
+  const nonSerializable = function nonSerializableClosure() {
     return nonSerializable;
   };
 
@@ -3717,7 +3683,7 @@ var Dict = function DictClosure() {
       return this._map[key] !== undefined;
     },
     forEach: function Dict_forEach(callback) {
-      for (var key in this._map) {
+      for (const key in this._map) {
         callback(key, this.get(key));
       }
     }
@@ -3809,7 +3775,7 @@ var Dict = function DictClosure() {
 
 exports.Dict = Dict;
 
-var Ref = function RefClosure() {
+const Ref = function RefClosure() {
   let refCache = Object.create(null);
 
   function Ref(num, gen) {
@@ -8594,8 +8560,9 @@ exports.JpxImage = JpxImage;
 /******/ 	// The require function
 /******/ 	function __w_pdfjs_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -8612,10 +8579,59 @@ exports.JpxImage = JpxImage;
 /******/ 	}
 /******/ 	
 /************************************************************************/
-/******/ 	// module exports must be returned from runtime so entry inlining is disabled
-/******/ 	// startup
-/******/ 	// Load entry module and return exports
-/******/ 	return __w_pdfjs_require__(0);
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
+(() => {
+var exports = __webpack_exports__;
+
+
+Object.defineProperty(exports, "__esModule", ({
+  value: true
+}));
+Object.defineProperty(exports, "getVerbosityLevel", ({
+  enumerable: true,
+  get: function () {
+    return _util.getVerbosityLevel;
+  }
+}));
+Object.defineProperty(exports, "setVerbosityLevel", ({
+  enumerable: true,
+  get: function () {
+    return _util.setVerbosityLevel;
+  }
+}));
+Object.defineProperty(exports, "Jbig2mage", ({
+  enumerable: true,
+  get: function () {
+    return _jbig.Jbig2mage;
+  }
+}));
+Object.defineProperty(exports, "JpegImage", ({
+  enumerable: true,
+  get: function () {
+    return _jpg.JpegImage;
+  }
+}));
+Object.defineProperty(exports, "JpxImage", ({
+  enumerable: true,
+  get: function () {
+    return _jpx.JpxImage;
+  }
+}));
+
+var _util = __w_pdfjs_require__(1);
+
+var _jbig = __w_pdfjs_require__(4);
+
+var _jpg = __w_pdfjs_require__(9);
+
+var _jpx = __w_pdfjs_require__(10);
+
+const pdfjsVersion = '2.8.335';
+const pdfjsBuild = '228adbf67';
+})();
+
+/******/ 	return __webpack_exports__;
 /******/ })()
 ;
 });

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
image_decoders/pdf.image_decoders.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
image_decoders/pdf.image_decoders.min.js


+ 0 - 0
es5/build/pdf.d.ts → legacy/build/pdf.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 224 - 407
legacy/build/pdf.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
legacy/build/pdf.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 21 - 0
legacy/build/pdf.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 39 - 0
legacy/build/pdf.sandbox.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
legacy/build/pdf.sandbox.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 21 - 0
legacy/build/pdf.sandbox.min.js


+ 1 - 1
es5/build/pdf.worker.entry.js → legacy/build/pdf.worker.entry.js

@@ -1,4 +1,4 @@
-/* Copyright 2020 Mozilla Foundation
+/* Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 230 - 225
legacy/build/pdf.worker.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
legacy/build/pdf.worker.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 21 - 0
legacy/build/pdf.worker.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 212 - 253
legacy/image_decoders/pdf.image_decoders.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
legacy/image_decoders/pdf.image_decoders.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 21 - 0
legacy/image_decoders/pdf.image_decoders.min.js


+ 0 - 0
es5/web/images/annotation-check.svg → legacy/web/images/annotation-check.svg


+ 0 - 0
es5/web/images/annotation-comment.svg → legacy/web/images/annotation-comment.svg


+ 0 - 0
es5/web/images/annotation-help.svg → legacy/web/images/annotation-help.svg


+ 0 - 0
es5/web/images/annotation-insert.svg → legacy/web/images/annotation-insert.svg


+ 0 - 0
es5/web/images/annotation-key.svg → legacy/web/images/annotation-key.svg


+ 0 - 0
es5/web/images/annotation-newparagraph.svg → legacy/web/images/annotation-newparagraph.svg


+ 0 - 0
es5/web/images/annotation-noicon.svg → legacy/web/images/annotation-noicon.svg


+ 0 - 0
es5/web/images/annotation-note.svg → legacy/web/images/annotation-note.svg


+ 0 - 0
es5/web/images/annotation-paragraph.svg → legacy/web/images/annotation-paragraph.svg


+ 0 - 0
es5/web/images/loading-icon.gif → legacy/web/images/loading-icon.gif


+ 0 - 0
es5/web/images/shadow.png → legacy/web/images/shadow.png


+ 178 - 6
es5/web/pdf_viewer.css → legacy/web/pdf_viewer.css

@@ -74,7 +74,6 @@
   cursor: default;
   -webkit-user-select: none;
      -moz-user-select: none;
-      -ms-user-select: none;
           user-select: none;
 }
 
@@ -278,6 +277,184 @@
   cursor: pointer;
 }
 
+*/* Copyright 2021 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.
+ */
+
+.xfaLayer {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 200;
+  transform-origin: 0 0;
+}
+
+.xfaLayer * {
+  color: inherit;
+  font: inherit;
+  -webkit-font-kerning: inherit;
+          font-kerning: inherit;
+  letter-spacing: inherit;
+  text-align: inherit;
+  text-decoration: inherit;
+  vertical-align: inherit;
+  box-sizing: border-box;
+}
+
+.xfaFont {
+  color: black;
+  font-weight: normal;
+  -webkit-font-kerning: none;
+          font-kerning: none;
+  font-size: 10px;
+  font-style: normal;
+  letter-spacing: 0;
+  text-decoration: none;
+  vertical-align: 0;
+}
+
+.xfaDraw {
+  z-index: 200;
+}
+
+.xfaExclgroup {
+  z-index: 300;
+}
+
+.xfaField {
+  z-index: 300;
+}
+
+.xfaSubform {
+  z-index: 100;
+}
+
+.xfaLabel {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  width: 100%;
+  height: 100%;
+}
+
+.xfaCaption {
+  flex: 1 1 auto;
+}
+
+.xfaTextfield,
+.xfaSelect {
+  width: 100%;
+  height: 100%;
+  flex: 1 1 auto;
+  border: none;
+}
+
+.xfaLabel > input[type="checkbox"] {
+  /* Use this trick to make the checkbox invisible but
+       but still focusable. */
+  position: absolute;
+  left: -99999px;
+}
+
+.xfaLabel > input[type="checkbox"]:focus + .xfaCheckboxMark {
+  box-shadow: 0 0 5px rgba(0, 0, 0, 0.7);
+}
+
+.xfaCheckboxMark {
+  cursor: pointer;
+  flex: 0 0 auto;
+  border-style: solid;
+  border-width: 2px;
+  border-color: #8f8f9d;
+  font-size: 10px;
+  line-height: 10px;
+  width: 10px;
+  height: 10px;
+  text-align: center;
+  vertical-align: middle;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+}
+
+.xfaCheckbox:checked + .xfaCheckboxMark::after {
+  content: attr(mark);
+}
+
+.xfaButton {
+  cursor: pointer;
+  width: 100%;
+  height: 100%;
+  border: none;
+  text-align: center;
+}
+
+.xfaButton:hover {
+  background: Highlight;
+}
+
+.xfaLrTb,
+.xfaRlTb,
+.xfaTb,
+.xfaPosition {
+  display: block;
+}
+
+.xfaPosition {
+  position: relative;
+}
+
+.xfaValignMiddle {
+  display: flex;
+  align-items: center;
+}
+
+.xfaLrTb > div {
+  display: inline;
+  float: left;
+}
+
+.xfaRlTb > div {
+  display: inline;
+  float: right;
+}
+
+.xfaTable {
+  display: flex;
+  flex-direction: column;
+}
+
+.xfaTable .xfaRow {
+  display: flex;
+  flex-direction: row;
+  flex: 1 1 auto;
+}
+
+.xfaTable .xfaRow > div {
+  flex: 1 1 auto;
+}
+
+.xfaTable .xfaRlRow {
+  display: flex;
+  flex-direction: row-reverse;
+  flex: 1;
+}
+
+.xfaTable .xfaRlRow > div {
+  flex: 1;
+}
+
 .pdfViewer .canvasWrapper {
   overflow: hidden;
 }
@@ -398,11 +575,6 @@
   border: 0;
 }
 
-.pdfPresentationMode:-ms-fullscreen .pdfViewer .page {
-  margin-bottom: 100%;
-  border: 0;
-}
-
 .pdfPresentationMode:fullscreen .pdfViewer .page {
   margin-bottom: 100%;
   border: 0;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1046 - 1296
legacy/web/pdf_viewer.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
legacy/web/pdf_viewer.js.map


+ 316 - 126
lib/core/annotation.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -46,13 +46,13 @@ var _stream = require("./stream.js");
 var _writer = require("./writer.js");
 
 class AnnotationFactory {
-  static create(xref, ref, pdfManager, idFactory) {
+  static create(xref, ref, pdfManager, idFactory, collectFields) {
     return pdfManager.ensureCatalog("acroForm").then(acroForm => {
-      return pdfManager.ensure(this, "_create", [xref, ref, pdfManager, idFactory, acroForm]);
+      return pdfManager.ensure(this, "_create", [xref, ref, pdfManager, idFactory, acroForm, collectFields]);
     });
   }
 
-  static _create(xref, ref, pdfManager, idFactory, acroForm) {
+  static _create(xref, ref, pdfManager, idFactory, acroForm, collectFields) {
     const dict = xref.fetchIfRef(ref);
 
     if (!(0, _primitives.isDict)(dict)) {
@@ -69,7 +69,8 @@ class AnnotationFactory {
       subtype,
       id,
       pdfManager,
-      acroForm: acroForm instanceof _primitives.Dict ? acroForm : _primitives.Dict.empty
+      acroForm: acroForm instanceof _primitives.Dict ? acroForm : _primitives.Dict.empty,
+      collectFields
     };
 
     switch (subtype) {
@@ -97,7 +98,7 @@ class AnnotationFactory {
             return new ChoiceWidgetAnnotation(parameters);
         }
 
-        (0, _util.warn)('Unimplemented widget field type "' + fieldType + '", ' + "falling back to base field type.");
+        (0, _util.warn)(`Unimplemented widget field type "${fieldType}", ` + "falling back to base field type.");
         return new WidgetAnnotation(parameters);
 
       case "Popup":
@@ -146,10 +147,12 @@ class AnnotationFactory {
         return new FileAttachmentAnnotation(parameters);
 
       default:
-        if (!subtype) {
-          (0, _util.warn)("Annotation is missing the required /Subtype.");
-        } else {
-          (0, _util.warn)('Unimplemented annotation type "' + subtype + '", ' + "falling back to base annotation.");
+        if (!collectFields) {
+          if (!subtype) {
+            (0, _util.warn)("Annotation is missing the required /Subtype.");
+          } else {
+            (0, _util.warn)(`Unimplemented annotation type "${subtype}", ` + "falling back to base annotation.");
+          }
         }
 
         return new Annotation(parameters);
@@ -160,6 +163,37 @@ class AnnotationFactory {
 
 exports.AnnotationFactory = AnnotationFactory;
 
+function getRgbColor(color) {
+  const rgbColor = new Uint8ClampedArray(3);
+
+  if (!Array.isArray(color)) {
+    return rgbColor;
+  }
+
+  switch (color.length) {
+    case 0:
+      return null;
+
+    case 1:
+      _colorspace.ColorSpace.singletons.gray.getRgbItem(color, 0, rgbColor, 0);
+
+      return rgbColor;
+
+    case 3:
+      _colorspace.ColorSpace.singletons.rgb.getRgbItem(color, 0, rgbColor, 0);
+
+      return rgbColor;
+
+    case 4:
+      _colorspace.ColorSpace.singletons.cmyk.getRgbItem(color, 0, rgbColor, 0);
+
+      return rgbColor;
+
+    default:
+      return rgbColor;
+  }
+}
+
 function getQuadPoints(dict, rect) {
   if (!dict.has("QuadPoints")) {
     return null;
@@ -248,6 +282,28 @@ class Annotation {
       rect: this.rectangle,
       subtype: params.subtype
     };
+
+    if (params.collectFields) {
+      const kids = dict.get("Kids");
+
+      if (Array.isArray(kids)) {
+        const kidIds = [];
+
+        for (const kid of kids) {
+          if ((0, _primitives.isRef)(kid)) {
+            kidIds.push(kid.toString());
+          }
+        }
+
+        if (kidIds.length !== 0) {
+          this.data.kidIds = kidIds;
+        }
+      }
+
+      this.data.actions = (0, _core_utils.collectActions)(params.xref, dict, _util.AnnotationActionEventType);
+      this.data.fieldName = this._constructFieldName(dict);
+    }
+
     this._fallbackFontDict = null;
   }
 
@@ -264,10 +320,10 @@ class Annotation {
   }
 
   isHidden(annotationStorage) {
-    const data = annotationStorage && annotationStorage[this.data.id];
+    const storageEntry = annotationStorage && annotationStorage.get(this.data.id);
 
-    if (data && "hidden" in data) {
-      return data.hidden;
+    if (storageEntry && storageEntry.hidden !== undefined) {
+      return storageEntry.hidden;
     }
 
     return this._hasFlag(this.flags, _util.AnnotationFlag.HIDDEN);
@@ -322,40 +378,7 @@ class Annotation {
   }
 
   setColor(color) {
-    const rgbColor = new Uint8ClampedArray(3);
-
-    if (!Array.isArray(color)) {
-      this.color = rgbColor;
-      return;
-    }
-
-    switch (color.length) {
-      case 0:
-        this.color = null;
-        break;
-
-      case 1:
-        _colorspace.ColorSpace.singletons.gray.getRgbItem(color, 0, rgbColor, 0);
-
-        this.color = rgbColor;
-        break;
-
-      case 3:
-        _colorspace.ColorSpace.singletons.rgb.getRgbItem(color, 0, rgbColor, 0);
-
-        this.color = rgbColor;
-        break;
-
-      case 4:
-        _colorspace.ColorSpace.singletons.cmyk.getRgbItem(color, 0, rgbColor, 0);
-
-        this.color = rgbColor;
-        break;
-
-      default:
-        this.color = rgbColor;
-        break;
-    }
+    this.color = getRgbColor(color);
   }
 
   setBorderStyle(borderStyle) {
@@ -466,6 +489,16 @@ class Annotation {
   }
 
   getFieldObject() {
+    if (this.data.kidIds) {
+      return {
+        id: this.data.id,
+        actions: this.data.actions,
+        name: this.data.fieldName,
+        type: "",
+        kidIds: this.data.kidIds
+      };
+    }
+
     return null;
   }
 
@@ -475,6 +508,48 @@ class Annotation {
     }
   }
 
+  _constructFieldName(dict) {
+    if (!dict.has("T") && !dict.has("Parent")) {
+      (0, _util.warn)("Unknown field name, falling back to empty field name.");
+      return "";
+    }
+
+    if (!dict.has("Parent")) {
+      return (0, _util.stringToPDFString)(dict.get("T"));
+    }
+
+    const fieldName = [];
+
+    if (dict.has("T")) {
+      fieldName.unshift((0, _util.stringToPDFString)(dict.get("T")));
+    }
+
+    let loopDict = dict;
+    const visited = new _primitives.RefSet();
+
+    if (dict.objId) {
+      visited.put(dict.objId);
+    }
+
+    while (loopDict.has("Parent")) {
+      loopDict = loopDict.get("Parent");
+
+      if (!(loopDict instanceof _primitives.Dict) || loopDict.objId && visited.has(loopDict.objId)) {
+        break;
+      }
+
+      if (loopDict.objId) {
+        visited.put(loopDict.objId);
+      }
+
+      if (loopDict.has("T")) {
+        fieldName.unshift((0, _util.stringToPDFString)(loopDict.get("T")));
+      }
+    }
+
+    return fieldName.join(".");
+  }
+
 }
 
 exports.Annotation = Annotation;
@@ -664,7 +739,25 @@ class MarkupAnnotation extends Annotation {
       buffer.push(`${fillColor[0]} ${fillColor[1]} ${fillColor[2]} rg`);
     }
 
-    for (const points of this.data.quadPoints) {
+    let pointsArray = this.data.quadPoints;
+
+    if (!pointsArray) {
+      pointsArray = [[{
+        x: this.rectangle[0],
+        y: this.rectangle[3]
+      }, {
+        x: this.rectangle[2],
+        y: this.rectangle[3]
+      }, {
+        x: this.rectangle[0],
+        y: this.rectangle[1]
+      }, {
+        x: this.rectangle[2],
+        y: this.rectangle[1]
+      }]];
+    }
+
+    for (const points of pointsArray) {
       const [mX, MX, mY, MY] = pointsCallback(buffer, points);
       minX = Math.min(minX, mX);
       maxX = Math.max(maxX, MX);
@@ -711,8 +804,15 @@ class WidgetAnnotation extends Annotation {
     const data = this.data;
     this.ref = params.ref;
     data.annotationType = _util.AnnotationType.WIDGET;
-    data.fieldName = this._constructFieldName(dict);
-    data.actions = (0, _core_utils.collectActions)(params.xref, dict, _util.AnnotationActionEventType);
+
+    if (data.fieldName === undefined) {
+      data.fieldName = this._constructFieldName(dict);
+    }
+
+    if (data.actions === undefined) {
+      data.actions = (0, _core_utils.collectActions)(params.xref, dict, _util.AnnotationActionEventType);
+    }
+
     const fieldValue = (0, _core_utils.getInheritableProperty)({
       dict,
       key: "V",
@@ -729,9 +829,9 @@ class WidgetAnnotation extends Annotation {
     const defaultAppearance = (0, _core_utils.getInheritableProperty)({
       dict,
       key: "DA"
-    }) || params.acroForm.get("DA") || "";
-    data.defaultAppearance = (0, _util.isString)(defaultAppearance) ? defaultAppearance : "";
-    data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(data.defaultAppearance);
+    }) || params.acroForm.get("DA");
+    this._defaultAppearance = (0, _util.isString)(defaultAppearance) ? defaultAppearance : "";
+    data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(this._defaultAppearance);
     const fieldType = (0, _core_utils.getInheritableProperty)({
       dict,
       key: "FT"
@@ -772,39 +872,6 @@ class WidgetAnnotation extends Annotation {
     }
   }
 
-  _constructFieldName(dict) {
-    if (!dict.has("T") && !dict.has("Parent")) {
-      (0, _util.warn)("Unknown field name, falling back to empty field name.");
-      return "";
-    }
-
-    if (!dict.has("Parent")) {
-      return (0, _util.stringToPDFString)(dict.get("T"));
-    }
-
-    const fieldName = [];
-
-    if (dict.has("T")) {
-      fieldName.unshift((0, _util.stringToPDFString)(dict.get("T")));
-    }
-
-    let loopDict = dict;
-
-    while (loopDict.has("Parent")) {
-      loopDict = loopDict.get("Parent");
-
-      if (!(0, _primitives.isDict)(loopDict)) {
-        break;
-      }
-
-      if (loopDict.has("T")) {
-        fieldName.unshift((0, _util.stringToPDFString)(loopDict.get("T")));
-      }
-    }
-
-    return fieldName.join(".");
-  }
-
   _decodeFormValue(formValue) {
     if (Array.isArray(formValue)) {
       return formValue.filter(item => (0, _util.isString)(item)).map(item => (0, _util.stringToPDFString)(item));
@@ -837,7 +904,7 @@ class WidgetAnnotation extends Annotation {
 
       const operatorList = new _operator_list.OperatorList();
 
-      if (!this.data.defaultAppearance || content === null) {
+      if (!this._defaultAppearance || content === null) {
         return operatorList;
       }
 
@@ -859,7 +926,12 @@ class WidgetAnnotation extends Annotation {
   }
 
   async save(evaluator, task, annotationStorage) {
-    const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
+    if (!annotationStorage) {
+      return null;
+    }
+
+    const storageEntry = annotationStorage.get(this.data.id);
+    const value = storageEntry && storageEntry.value;
 
     if (value === this.data.fieldValue || value === undefined) {
       return null;
@@ -932,30 +1004,37 @@ class WidgetAnnotation extends Annotation {
       return null;
     }
 
-    const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
+    const storageEntry = annotationStorage.get(this.data.id);
+    let value = storageEntry && storageEntry.value;
 
     if (value === undefined) {
       return null;
     }
 
+    value = value.trim();
+
     if (value === "") {
       return "";
     }
 
+    let lineCount = -1;
+
+    if (this.data.multiLine) {
+      lineCount = value.split(/\r\n|\r|\n/).length;
+    }
+
     const defaultPadding = 2;
     const hPadding = defaultPadding;
     const totalHeight = this.data.rect[3] - this.data.rect[1];
     const totalWidth = this.data.rect[2] - this.data.rect[0];
 
-    if (!this.data.defaultAppearance) {
-      this.data.defaultAppearance = "/Helvetica 0 Tf 0 g";
-      this.data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(this.data.defaultAppearance);
+    if (!this._defaultAppearance) {
+      this.data.defaultAppearanceData = (0, _default_appearance.parseDefaultAppearance)(this._defaultAppearance = "/Helvetica 0 Tf 0 g");
     }
 
-    const font = await this._getFontData(evaluator, task);
-
-    const fontSize = this._computeFontSize(font, totalHeight);
+    const [defaultAppearance, fontSize] = this._computeFontSize(totalHeight, lineCount);
 
+    const font = await this._getFontData(evaluator, task);
     let descent = font.descent;
 
     if (isNaN(descent)) {
@@ -963,7 +1042,6 @@ class WidgetAnnotation extends Annotation {
     }
 
     const vPadding = defaultPadding + Math.abs(descent) * fontSize;
-    const defaultAppearance = this.data.defaultAppearance;
     const alignment = this.data.textAlignment;
 
     if (this.data.multiLine) {
@@ -999,42 +1077,43 @@ class WidgetAnnotation extends Annotation {
       fontName,
       fontSize
     } = this.data.defaultAppearanceData;
-    await evaluator.handleSetFont(this._fieldResources.mergedResources, [fontName, fontSize], null, operatorList, task, initialState, null);
+    await evaluator.handleSetFont(this._fieldResources.mergedResources, [fontName && _primitives.Name.get(fontName), fontSize], null, operatorList, task, initialState, null);
     return initialState.font;
   }
 
-  _computeFontSize(font, height) {
-    let fontSize = this.data.defaultAppearanceData.fontSize;
+  _computeFontSize(height, lineCount) {
+    let {
+      fontSize
+    } = this.data.defaultAppearanceData;
 
     if (!fontSize) {
-      const {
-        fontColor,
-        fontName
-      } = this.data.defaultAppearanceData;
-      let capHeight;
+      const roundWithOneDigit = x => Math.round(x * 10) / 10;
 
-      if (font.capHeight) {
-        capHeight = font.capHeight;
-      } else {
-        const glyphs = font.charsToGlyphs(font.encodeString("M").join(""));
+      const FONT_FACTOR = 0.8;
 
-        if (glyphs.length === 1 && glyphs[0].width) {
-          const em = glyphs[0].width / 1000;
-          capHeight = 0.7 * em;
-        } else {
-          capHeight = 0.7;
-        }
+      if (lineCount === -1) {
+        fontSize = roundWithOneDigit(FONT_FACTOR * height);
+      } else {
+        fontSize = 10;
+        let lineHeight = fontSize / FONT_FACTOR;
+        let numberOfLines = Math.round(height / lineHeight);
+        numberOfLines = Math.max(numberOfLines, lineCount);
+        lineHeight = height / numberOfLines;
+        fontSize = roundWithOneDigit(FONT_FACTOR * lineHeight);
       }
 
-      fontSize = Math.max(1, Math.floor(height / (1.5 * capHeight)));
-      this.data.defaultAppearance = (0, _default_appearance.createDefaultAppearance)({
+      const {
+        fontName,
+        fontColor
+      } = this.data.defaultAppearanceData;
+      this._defaultAppearance = (0, _default_appearance.createDefaultAppearance)({
         fontSize,
         fontName,
         fontColor
       });
     }
 
-    return fontSize;
+    return [this._defaultAppearance, fontSize];
   }
 
   _renderText(text, font, fontSize, totalWidth, alignment, hPadding, vPadding) {
@@ -1067,9 +1146,9 @@ class WidgetAnnotation extends Annotation {
       appearanceResources,
       acroFormResources
     } = this._fieldResources;
-    const fontNameStr = this.data.defaultAppearanceData && this.data.defaultAppearanceData.fontName.name;
+    const fontName = this.data.defaultAppearanceData && this.data.defaultAppearanceData.fontName;
 
-    if (!fontNameStr) {
+    if (!fontName) {
       return localResources || _primitives.Dict.empty;
     }
 
@@ -1077,7 +1156,7 @@ class WidgetAnnotation extends Annotation {
       if (resources instanceof _primitives.Dict) {
         const localFont = resources.get("Font");
 
-        if (localFont instanceof _primitives.Dict && localFont.has(fontNameStr)) {
+        if (localFont instanceof _primitives.Dict && localFont.has(fontName)) {
           return resources;
         }
       }
@@ -1086,9 +1165,9 @@ class WidgetAnnotation extends Annotation {
     if (acroFormResources instanceof _primitives.Dict) {
       const acroFormFont = acroFormResources.get("Font");
 
-      if (acroFormFont instanceof _primitives.Dict && acroFormFont.has(fontNameStr)) {
+      if (acroFormFont instanceof _primitives.Dict && acroFormFont.has(fontName)) {
         const subFontDict = new _primitives.Dict(xref);
-        subFontDict.set(fontNameStr, acroFormFont.getRaw(fontNameStr));
+        subFontDict.set(fontName, acroFormFont.getRaw(fontName));
         const subResourcesDict = new _primitives.Dict(xref);
         subResourcesDict.set("Font", subFontDict);
         return _primitives.Dict.merge({
@@ -1289,7 +1368,8 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
     }
 
     if (annotationStorage) {
-      const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
+      const storageEntry = annotationStorage.get(this.data.id);
+      const value = storageEntry && storageEntry.value;
 
       if (value === undefined) {
         return super.getOperatorList(evaluator, task, renderForms, annotationStorage);
@@ -1330,7 +1410,12 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
   }
 
   async _saveCheckbox(evaluator, task, annotationStorage) {
-    const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
+    if (!annotationStorage) {
+      return null;
+    }
+
+    const storageEntry = annotationStorage.get(this.data.id);
+    const value = storageEntry && storageEntry.value;
 
     if (value === undefined) {
       return null;
@@ -1376,7 +1461,12 @@ class ButtonWidgetAnnotation extends WidgetAnnotation {
   }
 
   async _saveRadioButton(evaluator, task, annotationStorage) {
-    const value = annotationStorage[this.data.id] && annotationStorage[this.data.id].value;
+    if (!annotationStorage) {
+      return null;
+    }
+
+    const storageEntry = annotationStorage.get(this.data.id);
+    const value = storageEntry && storageEntry.value;
 
     if (value === undefined) {
       return null;
@@ -1629,6 +1719,7 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation {
       multipleSelection: this.data.multiSelect,
       hidden: this.data.hidden,
       actions: this.data.actions,
+      items: this.data.options,
       type
     };
   }
@@ -1749,7 +1840,29 @@ class LineAnnotation extends MarkupAnnotation {
   constructor(parameters) {
     super(parameters);
     this.data.annotationType = _util.AnnotationType.LINE;
-    this.data.lineCoordinates = _util.Util.normalizeRect(parameters.dict.getArray("L"));
+    const lineCoordinates = parameters.dict.getArray("L");
+    this.data.lineCoordinates = _util.Util.normalizeRect(lineCoordinates);
+
+    if (!this.appearance) {
+      const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0];
+      const borderWidth = this.borderStyle.width;
+
+      if ((0, _util.isArrayEqual)(this.rectangle, [0, 0, 0, 0])) {
+        this.rectangle = [this.data.lineCoordinates[0] - 2 * borderWidth, this.data.lineCoordinates[1] - 2 * borderWidth, this.data.lineCoordinates[2] + 2 * borderWidth, this.data.lineCoordinates[3] + 2 * borderWidth];
+      }
+
+      this._setDefaultAppearance({
+        xref: parameters.xref,
+        extra: `${borderWidth} w`,
+        strokeColor,
+        pointsCallback: (buffer, points) => {
+          buffer.push(`${lineCoordinates[0]} ${lineCoordinates[1]} m`);
+          buffer.push(`${lineCoordinates[2]} ${lineCoordinates[3]} l`);
+          buffer.push("S");
+          return [points[0].x - borderWidth, points[1].x + borderWidth, points[3].y - borderWidth, points[1].y + borderWidth];
+        }
+      });
+    }
   }
 
 }
@@ -1758,6 +1871,39 @@ class SquareAnnotation extends MarkupAnnotation {
   constructor(parameters) {
     super(parameters);
     this.data.annotationType = _util.AnnotationType.SQUARE;
+
+    if (!this.appearance) {
+      const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0];
+      let fillColor = null;
+      let interiorColor = parameters.dict.getArray("IC");
+
+      if (interiorColor) {
+        interiorColor = getRgbColor(interiorColor);
+        fillColor = interiorColor ? Array.from(interiorColor).map(c => c / 255) : null;
+      }
+
+      this._setDefaultAppearance({
+        xref: parameters.xref,
+        extra: `${this.borderStyle.width} w`,
+        strokeColor,
+        fillColor,
+        pointsCallback: (buffer, points) => {
+          const x = points[2].x + this.borderStyle.width / 2;
+          const y = points[2].y + this.borderStyle.width / 2;
+          const width = points[3].x - points[2].x - this.borderStyle.width;
+          const height = points[1].y - points[3].y - this.borderStyle.width;
+          buffer.push(`${x} ${y} ${width} ${height} re`);
+
+          if (fillColor) {
+            buffer.push("B");
+          } else {
+            buffer.push("S");
+          }
+
+          return [points[0].x, points[1].x, points[3].y, points[1].y];
+        }
+      });
+    }
   }
 
 }
@@ -1766,6 +1912,50 @@ class CircleAnnotation extends MarkupAnnotation {
   constructor(parameters) {
     super(parameters);
     this.data.annotationType = _util.AnnotationType.CIRCLE;
+
+    if (!this.appearance) {
+      const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0];
+      let fillColor = null;
+      let interiorColor = parameters.dict.getArray("IC");
+
+      if (interiorColor) {
+        interiorColor = getRgbColor(interiorColor);
+        fillColor = interiorColor ? Array.from(interiorColor).map(c => c / 255) : null;
+      }
+
+      const controlPointsDistance = 4 / 3 * Math.tan(Math.PI / (2 * 4));
+
+      this._setDefaultAppearance({
+        xref: parameters.xref,
+        extra: `${this.borderStyle.width} w`,
+        strokeColor,
+        fillColor,
+        pointsCallback: (buffer, points) => {
+          const x0 = points[0].x + this.borderStyle.width / 2;
+          const y0 = points[0].y - this.borderStyle.width / 2;
+          const x1 = points[3].x - this.borderStyle.width / 2;
+          const y1 = points[3].y + this.borderStyle.width / 2;
+          const xMid = x0 + (x1 - x0) / 2;
+          const yMid = y0 + (y1 - y0) / 2;
+          const xOffset = (x1 - x0) / 2 * controlPointsDistance;
+          const yOffset = (y1 - y0) / 2 * controlPointsDistance;
+          buffer.push(`${xMid} ${y1} m`);
+          buffer.push(`${xMid + xOffset} ${y1} ${x1} ${yMid + yOffset} ${x1} ${yMid} c`);
+          buffer.push(`${x1} ${yMid - yOffset} ${xMid + xOffset} ${y0} ${xMid} ${y0} c`);
+          buffer.push(`${xMid - xOffset} ${y0} ${x0} ${yMid - yOffset} ${x0} ${yMid} c`);
+          buffer.push(`${x0} ${yMid + yOffset} ${xMid - xOffset} ${y1} ${xMid} ${y1} c`);
+          buffer.push("h");
+
+          if (fillColor) {
+            buffer.push("B");
+          } else {
+            buffer.push("S");
+          }
+
+          return [points[0].x, points[1].x, points[3].y, points[1].y];
+        }
+      });
+    }
   }
 
 }

+ 1 - 1
lib/core/arithmetic_decoder.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
lib/core/bidi.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
lib/core/ccitt.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 2 - 2
lib/core/ccitt_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ var _ccitt = require("./ccitt.js");
 
 var _stream = require("./stream.js");
 
-var CCITTFaxStream = function CCITTFaxStreamClosure() {
+const CCITTFaxStream = function CCITTFaxStreamClosure() {
   function CCITTFaxStream(str, maybeLength, params) {
     this.str = str;
     this.dict = str.dict;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 2
lib/core/cff_parser.js


+ 1 - 1
lib/core/charsets.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
lib/core/chunked_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 65 - 75
lib/core/cmap.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -319,21 +319,21 @@ var BinaryCMapReader = function BinaryCMapReaderClosure() {
   var MAX_NUM_SIZE = 16;
   var MAX_ENCODED_NUM_SIZE = 19;
 
-  function BinaryCMapStream(data) {
-    this.buffer = data;
-    this.pos = 0;
-    this.end = data.length;
-    this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE);
-  }
+  class BinaryCMapStream {
+    constructor(data) {
+      this.buffer = data;
+      this.pos = 0;
+      this.end = data.length;
+      this.tmpBuf = new Uint8Array(MAX_ENCODED_NUM_SIZE);
+    }
 
-  BinaryCMapStream.prototype = {
     readByte() {
       if (this.pos >= this.end) {
         return -1;
       }
 
       return this.buffer[this.pos++];
-    },
+    }
 
     readNumber() {
       var n = 0;
@@ -351,17 +351,17 @@ var BinaryCMapReader = function BinaryCMapReaderClosure() {
       } while (!last);
 
       return n;
-    },
+    }
 
     readSigned() {
       var n = this.readNumber();
       return n & 1 ? ~(n >>> 1) : n >>> 1;
-    },
+    }
 
     readHex(num, size) {
       num.set(this.buffer.subarray(this.pos, this.pos + size + 1));
       this.pos += size + 1;
-    },
+    }
 
     readHexNumber(num, size) {
       var last;
@@ -394,7 +394,7 @@ var BinaryCMapReader = function BinaryCMapReaderClosure() {
         buffer >>= 8;
         bufferSize -= 8;
       }
-    },
+    }
 
     readHexSigned(num, size) {
       this.readHexNumber(num, size);
@@ -405,7 +405,7 @@ var BinaryCMapReader = function BinaryCMapReaderClosure() {
         c = (c & 1) << 8 | num[i];
         num[i] = c >> 1 ^ sign;
       }
-    },
+    }
 
     readString() {
       var len = this.readNumber();
@@ -418,10 +418,10 @@ var BinaryCMapReader = function BinaryCMapReaderClosure() {
       return s;
     }
 
-  };
+  }
 
-  function processBinaryCMap(data, cMap, extend) {
-    return new Promise(function (resolve, reject) {
+  class BinaryCMapReader {
+    async process(data, cMap, extend) {
       var stream = new BinaryCMapStream(data);
       var header = stream.readByte();
       cMap.vertical = !!(header & 1);
@@ -455,7 +455,7 @@ var BinaryCMapReader = function BinaryCMapReaderClosure() {
         var dataSize = b & 15;
 
         if (dataSize + 1 > MAX_NUM_SIZE) {
-          throw new Error("processBinaryCMap: Invalid dataSize.");
+          throw new Error("BinaryCMapReader.process: Invalid dataSize.");
         }
 
         var ucs2DataSize = 1;
@@ -588,25 +588,19 @@ var BinaryCMapReader = function BinaryCMapReaderClosure() {
             break;
 
           default:
-            reject(new Error("processBinaryCMap: Unknown type: " + type));
-            return;
+            throw new Error(`BinaryCMapReader.process - unknown type: ${type}`);
         }
       }
 
       if (useCMap) {
-        resolve(extend(useCMap));
-        return;
+        return extend(useCMap);
       }
 
-      resolve(cMap);
-    });
-  }
+      return cMap;
+    }
 
-  function BinaryCMapReader() {}
+  }
 
-  BinaryCMapReader.prototype = {
-    process: processBinaryCMap
-  };
   return BinaryCMapReader;
 }();
 
@@ -785,7 +779,7 @@ var CMapFactory = function CMapFactoryClosure() {
     }
   }
 
-  function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {
+  async function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {
     var previous;
     var embeddedUseCMap;
 
@@ -854,65 +848,63 @@ var CMapFactory = function CMapFactoryClosure() {
       return extendCMap(cMap, fetchBuiltInCMap, useCMap);
     }
 
-    return Promise.resolve(cMap);
+    return cMap;
   }
 
-  function extendCMap(cMap, fetchBuiltInCMap, useCMap) {
-    return createBuiltInCMap(useCMap, fetchBuiltInCMap).then(function (newCMap) {
-      cMap.useCMap = newCMap;
+  async function extendCMap(cMap, fetchBuiltInCMap, useCMap) {
+    cMap.useCMap = await createBuiltInCMap(useCMap, fetchBuiltInCMap);
 
-      if (cMap.numCodespaceRanges === 0) {
-        var useCodespaceRanges = cMap.useCMap.codespaceRanges;
+    if (cMap.numCodespaceRanges === 0) {
+      var useCodespaceRanges = cMap.useCMap.codespaceRanges;
 
-        for (var i = 0; i < useCodespaceRanges.length; i++) {
-          cMap.codespaceRanges[i] = useCodespaceRanges[i].slice();
-        }
-
-        cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges;
+      for (var i = 0; i < useCodespaceRanges.length; i++) {
+        cMap.codespaceRanges[i] = useCodespaceRanges[i].slice();
       }
 
-      cMap.useCMap.forEach(function (key, value) {
-        if (!cMap.contains(key)) {
-          cMap.mapOne(key, cMap.useCMap.lookup(key));
-        }
-      });
-      return cMap;
+      cMap.numCodespaceRanges = cMap.useCMap.numCodespaceRanges;
+    }
+
+    cMap.useCMap.forEach(function (key, value) {
+      if (!cMap.contains(key)) {
+        cMap.mapOne(key, cMap.useCMap.lookup(key));
+      }
     });
+    return cMap;
   }
 
-  function createBuiltInCMap(name, fetchBuiltInCMap) {
+  async function createBuiltInCMap(name, fetchBuiltInCMap) {
     if (name === "Identity-H") {
-      return Promise.resolve(new IdentityCMap(false, 2));
+      return new IdentityCMap(false, 2);
     } else if (name === "Identity-V") {
-      return Promise.resolve(new IdentityCMap(true, 2));
+      return new IdentityCMap(true, 2);
     }
 
     if (!BUILT_IN_CMAPS.includes(name)) {
-      return Promise.reject(new Error("Unknown CMap name: " + name));
+      throw new Error("Unknown CMap name: " + name);
     }
 
     if (!fetchBuiltInCMap) {
-      return Promise.reject(new Error("Built-in CMap parameters are not provided."));
+      throw new Error("Built-in CMap parameters are not provided.");
     }
 
-    return fetchBuiltInCMap(name).then(function (data) {
-      var cMapData = data.cMapData,
-          compressionType = data.compressionType;
-      var cMap = new CMap(true);
+    const {
+      cMapData,
+      compressionType
+    } = await fetchBuiltInCMap(name);
+    var cMap = new CMap(true);
 
-      if (compressionType === _util.CMapCompressionType.BINARY) {
-        return new BinaryCMapReader().process(cMapData, cMap, function (useCMap) {
-          return extendCMap(cMap, fetchBuiltInCMap, useCMap);
-        });
-      }
+    if (compressionType === _util.CMapCompressionType.BINARY) {
+      return new BinaryCMapReader().process(cMapData, cMap, useCMap => {
+        return extendCMap(cMap, fetchBuiltInCMap, useCMap);
+      });
+    }
 
-      if (compressionType === _util.CMapCompressionType.NONE) {
-        var lexer = new _parser.Lexer(new _stream.Stream(cMapData));
-        return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
-      }
+    if (compressionType === _util.CMapCompressionType.NONE) {
+      var lexer = new _parser.Lexer(new _stream.Stream(cMapData));
+      return parseCMap(cMap, lexer, fetchBuiltInCMap, null);
+    }
 
-      return Promise.reject(new Error("TODO: Only BINARY/NONE CMap compression is currently supported."));
-    });
+    throw new Error("TODO: Only BINARY/NONE CMap compression is currently supported.");
   }
 
   return {
@@ -924,15 +916,13 @@ var CMapFactory = function CMapFactoryClosure() {
       if ((0, _primitives.isName)(encoding)) {
         return createBuiltInCMap(encoding.name, fetchBuiltInCMap);
       } else if ((0, _primitives.isStream)(encoding)) {
-        var cMap = new CMap();
-        var lexer = new _parser.Lexer(encoding);
-        return parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap).then(function (parsedCMap) {
-          if (parsedCMap.isIdentityCMap) {
-            return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap);
-          }
+        const parsedCMap = await parseCMap(new CMap(), new _parser.Lexer(encoding), fetchBuiltInCMap, useCMap);
+
+        if (parsedCMap.isIdentityCMap) {
+          return createBuiltInCMap(parsedCMap.name, fetchBuiltInCMap);
+        }
 
-          return parsedCMap;
-        });
+        return parsedCMap;
       }
 
       throw new Error("Encoding required.");

+ 2 - 2
lib/core/colorspace.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -954,7 +954,7 @@ const LabCS = function LabCSClosure() {
     let result;
 
     if (x >= 6 / 29) {
-      result = x * x * x;
+      result = x ** 3;
     } else {
       result = 108 / 841 * (x - 4 / 29);
     }

+ 83 - 21
lib/core/core_utils.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ Object.defineProperty(exports, "__esModule", {
   value: true
 });
 exports.collectActions = collectActions;
+exports.encodeToXmlString = encodeToXmlString;
 exports.escapePDFName = escapePDFName;
 exports.getArrayLookupTableFactory = getArrayLookupTableFactory;
 exports.getInheritableProperty = getInheritableProperty;
@@ -99,11 +100,14 @@ function getInheritableProperty({
   getArray = false,
   stopWhenFound = true
 }) {
-  const LOOP_LIMIT = 100;
-  let loopCount = 0;
   let values;
+  const visited = new _primitives.RefSet();
+
+  while (dict instanceof _primitives.Dict && !(dict.objId && visited.has(dict.objId))) {
+    if (dict.objId) {
+      visited.put(dict.objId);
+    }
 
-  while (dict) {
     const value = getArray ? dict.getArray(key) : dict.get(key);
 
     if (value !== undefined) {
@@ -118,11 +122,6 @@ function getInheritableProperty({
       values.push(value);
     }
 
-    if (++loopCount > LOOP_LIMIT) {
-      (0, _util.warn)(`getInheritableProperty: maximum loop count exceeded for "${key}"`);
-      break;
-    }
-
     dict = dict.get("Parent");
   }
 
@@ -272,25 +271,36 @@ function _collectJS(entry, xref, list, parents) {
 
 function collectActions(xref, dict, eventType) {
   const actions = Object.create(null);
+  const additionalActionsDicts = getInheritableProperty({
+    dict,
+    key: "AA",
+    stopWhenFound: false
+  });
 
-  if (dict.has("AA")) {
-    const additionalActions = dict.get("AA");
-
-    for (const key of additionalActions.getKeys()) {
-      const action = eventType[key];
+  if (additionalActionsDicts) {
+    for (let i = additionalActionsDicts.length - 1; i >= 0; i--) {
+      const additionalActions = additionalActionsDicts[i];
 
-      if (!action) {
+      if (!(additionalActions instanceof _primitives.Dict)) {
         continue;
       }
 
-      const actionDict = additionalActions.getRaw(key);
-      const parents = new _primitives.RefSet();
-      const list = [];
+      for (const key of additionalActions.getKeys()) {
+        const action = eventType[key];
+
+        if (!action) {
+          continue;
+        }
+
+        const actionDict = additionalActions.getRaw(key);
+        const parents = new _primitives.RefSet();
+        const list = [];
 
-      _collectJS(actionDict, xref, list, parents);
+        _collectJS(actionDict, xref, list, parents);
 
-      if (list.length > 0) {
-        actions[action] = list;
+        if (list.length > 0) {
+          actions[action] = list;
+        }
       }
     }
   }
@@ -308,4 +318,56 @@ function collectActions(xref, dict, eventType) {
   }
 
   return (0, _util.objectSize)(actions) > 0 ? actions : null;
+}
+
+const XMLEntities = {
+  0x3c: "&lt;",
+  0x3e: "&gt;",
+  0x26: "&amp;",
+  0x22: "&quot;",
+  0x27: "&apos;"
+};
+
+function encodeToXmlString(str) {
+  const buffer = [];
+  let start = 0;
+
+  for (let i = 0, ii = str.length; i < ii; i++) {
+    const char = str.codePointAt(i);
+
+    if (0x20 <= char && char <= 0x7e) {
+      const entity = XMLEntities[char];
+
+      if (entity) {
+        if (start < i) {
+          buffer.push(str.substring(start, i));
+        }
+
+        buffer.push(entity);
+        start = i + 1;
+      }
+    } else {
+      if (start < i) {
+        buffer.push(str.substring(start, i));
+      }
+
+      buffer.push(`&#x${char.toString(16).toUpperCase()};`);
+
+      if (char > 0xd7ff && (char < 0xe000 || char > 0xfffd)) {
+        i++;
+      }
+
+      start = i + 1;
+    }
+  }
+
+  if (buffer.length === 0) {
+    return str;
+  }
+
+  if (start < str.length) {
+    buffer.push(str.substring(start, str.length));
+  }
+
+  return buffer.join("");
 }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 122 - 110
lib/core/crypto.js


+ 8 - 8
lib/core/default_appearance.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,8 +27,6 @@ Object.defineProperty(exports, "__esModule", {
 exports.createDefaultAppearance = createDefaultAppearance;
 exports.parseDefaultAppearance = parseDefaultAppearance;
 
-var _primitives = require("./primitives.js");
-
 var _util = require("../shared/util.js");
 
 var _colorspace = require("./colorspace.js");
@@ -37,6 +35,8 @@ var _core_utils = require("./core_utils.js");
 
 var _evaluator = require("./evaluator.js");
 
+var _primitives = require("./primitives.js");
+
 var _stream = require("./stream.js");
 
 class DefaultAppearanceEvaluator extends _evaluator.EvaluatorPreprocessor {
@@ -51,8 +51,8 @@ class DefaultAppearanceEvaluator extends _evaluator.EvaluatorPreprocessor {
     };
     const result = {
       fontSize: 0,
-      fontName: _primitives.Name.get(""),
-      fontColor: new Uint8ClampedArray([0, 0, 0])
+      fontName: "",
+      fontColor: new Uint8ClampedArray(3)
     };
 
     try {
@@ -76,8 +76,8 @@ class DefaultAppearanceEvaluator extends _evaluator.EvaluatorPreprocessor {
           case _util.OPS.setFont:
             const [fontName, fontSize] = args;
 
-            if ((0, _primitives.isName)(fontName)) {
-              result.fontName = fontName;
+            if (fontName instanceof _primitives.Name) {
+              result.fontName = fontName.name;
             }
 
             if (typeof fontSize === "number" && fontSize > 0) {
@@ -128,5 +128,5 @@ function createDefaultAppearance({
     colorCmd = Array.from(fontColor).map(c => (c / 255).toFixed(2)).join(" ") + " rg";
   }
 
-  return `/${(0, _core_utils.escapePDFName)(fontName.name)} ${fontSize} Tf ${colorCmd}`;
+  return `/${(0, _core_utils.escapePDFName)(fontName)} ${fontSize} Tf ${colorCmd}`;
 }

+ 125 - 5
lib/core/document.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -46,6 +46,8 @@ var _operator_list = require("./operator_list.js");
 
 var _evaluator = require("./evaluator.js");
 
+var _factory = require("./xfa/factory.js");
+
 const DEFAULT_USER_UNIT = 1.0;
 const LETTER_SIZE_MEDIABOX = [0, 0, 612, 792];
 
@@ -64,7 +66,8 @@ class Page {
     fontCache,
     builtInCMapCache,
     globalImageCache,
-    nonBlendModesSet
+    nonBlendModesSet,
+    xfaFactory
   }) {
     this.pdfManager = pdfManager;
     this.pageIndex = pageIndex;
@@ -77,6 +80,7 @@ class Page {
     this.nonBlendModesSet = nonBlendModesSet;
     this.evaluatorOptions = pdfManager.evaluatorOptions;
     this.resourcesPromise = null;
+    this.xfaFactory = xfaFactory;
     const idCounters = {
       obj: 0
     };
@@ -119,6 +123,14 @@ class Page {
   }
 
   _getBoundingBox(name) {
+    if (this.xfaData) {
+      const {
+        width,
+        height
+      } = this.xfaData.attributes.style;
+      return [0, 0, parseInt(width), parseInt(height)];
+    }
+
     const box = this._getInheritableProperty(name, true);
 
     if (Array.isArray(box) && box.length === 4) {
@@ -208,6 +220,14 @@ class Page {
     return stream;
   }
 
+  get xfaData() {
+    if (this.xfaFactory) {
+      return (0, _util.shadow)(this, "xfaData", this.xfaFactory.getPage(this.pageIndex));
+    }
+
+    return (0, _util.shadow)(this, "xfaData", null);
+  }
+
   save(handler, task, annotationStorage) {
     const partialEvaluator = new _evaluator.PartialEvaluator({
       xref: this.xref,
@@ -377,7 +397,7 @@ class Page {
       const annotationPromises = [];
 
       for (const annotationRef of this.annotations) {
-        annotationPromises.push(_annotation.AnnotationFactory.create(this.xref, annotationRef, this.pdfManager, this._localIdFactory).catch(function (reason) {
+        annotationPromises.push(_annotation.AnnotationFactory.create(this.xref, annotationRef, this.pdfManager, this._localIdFactory, false).catch(function (reason) {
           (0, _util.warn)(`_parsedAnnotations: "${reason}".`);
           return null;
         }));
@@ -603,6 +623,10 @@ class PDFDocument {
   }
 
   get numPages() {
+    if (this.xfaFactory) {
+      return (0, _util.shadow)(this, "numPages", this.xfaFactory.numberPages);
+    }
+
     const linearization = this.linearization;
     const num = linearization ? linearization.numPages : this.catalog.numPages;
     return (0, _util.shadow)(this, "numPages", num);
@@ -638,6 +662,84 @@ class PDFDocument {
     });
   }
 
+  get xfaData() {
+    const acroForm = this.catalog.acroForm;
+
+    if (!acroForm) {
+      return null;
+    }
+
+    const xfa = acroForm.get("XFA");
+    const entries = {
+      "xdp:xdp": "",
+      template: "",
+      datasets: "",
+      config: "",
+      connectionSet: "",
+      localeSet: "",
+      stylesheet: "",
+      "/xdp:xdp": ""
+    };
+
+    if ((0, _primitives.isStream)(xfa) && !xfa.isEmpty) {
+      try {
+        entries["xdp:xdp"] = (0, _util.stringToUTF8String)((0, _util.bytesToString)(xfa.getBytes()));
+        return entries;
+      } catch (_) {
+        (0, _util.warn)("XFA - Invalid utf-8 string.");
+        return null;
+      }
+    }
+
+    if (!Array.isArray(xfa) || xfa.length === 0) {
+      return null;
+    }
+
+    for (let i = 0, ii = xfa.length; i < ii; i += 2) {
+      let name;
+
+      if (i === 0) {
+        name = "xdp:xdp";
+      } else if (i === ii - 2) {
+        name = "/xdp:xdp";
+      } else {
+        name = xfa[i];
+      }
+
+      if (!entries.hasOwnProperty(name)) {
+        continue;
+      }
+
+      const data = this.xref.fetchIfRef(xfa[i + 1]);
+
+      if (!(0, _primitives.isStream)(data) || data.isEmpty) {
+        continue;
+      }
+
+      try {
+        entries[name] = (0, _util.stringToUTF8String)((0, _util.bytesToString)(data.getBytes()));
+      } catch (_) {
+        (0, _util.warn)("XFA - Invalid utf-8 string.");
+        return null;
+      }
+    }
+
+    return entries;
+  }
+
+  get xfaFactory() {
+    if (this.pdfManager.enableXfa && this.formInfo.hasXfa && !this.formInfo.hasAcroForm) {
+      const data = this.xfaData;
+      return (0, _util.shadow)(this, "xfaFactory", data ? new _factory.XFAFactory(data) : null);
+    }
+
+    return (0, _util.shadow)(this, "xfaFaxtory", null);
+  }
+
+  get isPureXfa() {
+    return this.xfaFactory !== null;
+  }
+
   get formInfo() {
     const formInfo = {
       hasFields: false,
@@ -797,6 +899,23 @@ class PDFDocument {
       catalog,
       linearization
     } = this;
+
+    if (this.xfaFactory) {
+      return Promise.resolve(new Page({
+        pdfManager: this.pdfManager,
+        xref: this.xref,
+        pageIndex,
+        pageDict: _primitives.Dict.empty,
+        ref: null,
+        globalIdFactory: this._globalIdFactory,
+        fontCache: catalog.fontCache,
+        builtInCMapCache: catalog.builtInCMapCache,
+        globalImageCache: catalog.globalImageCache,
+        nonBlendModesSet: catalog.nonBlendModesSet,
+        xfaFactory: this.xfaFactory
+      }));
+    }
+
     const promise = linearization && linearization.pageFirst === pageIndex ? this._getLinearizationPage(pageIndex) : catalog.getPageDict(pageIndex);
     return this._pagePromises[pageIndex] = promise.then(([pageDict, ref]) => {
       return new Page({
@@ -809,7 +928,8 @@ class PDFDocument {
         fontCache: catalog.fontCache,
         builtInCMapCache: catalog.builtInCMapCache,
         globalImageCache: catalog.globalImageCache,
-        nonBlendModesSet: catalog.nonBlendModesSet
+        nonBlendModesSet: catalog.nonBlendModesSet,
+        xfaFactory: null
       });
     });
   }
@@ -849,7 +969,7 @@ class PDFDocument {
       promises.set(name, []);
     }
 
-    promises.get(name).push(_annotation.AnnotationFactory.create(this.xref, fieldRef, this.pdfManager, this._localIdFactory).then(annotation => annotation && annotation.getFieldObject()).catch(function (reason) {
+    promises.get(name).push(_annotation.AnnotationFactory.create(this.xref, fieldRef, this.pdfManager, this._localIdFactory, true).then(annotation => annotation && annotation.getFieldObject()).catch(function (reason) {
       (0, _util.warn)(`_collectFieldObjects: "${reason}".`);
       return null;
     }));

+ 1 - 1
lib/core/encodings.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 47 - 43
lib/core/evaluator.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,12 +32,12 @@ var _cmap = require("./cmap.js");
 
 var _primitives = require("./primitives.js");
 
+var _stream = require("./stream.js");
+
 var _fonts = require("./fonts.js");
 
 var _encodings = require("./encodings.js");
 
-var _core_utils = require("./core_utils.js");
-
 var _unicode = require("./unicode.js");
 
 var _standard_fonts = require("./standard_fonts.js");
@@ -54,10 +54,10 @@ var _bidi = require("./bidi.js");
 
 var _colorspace = require("./colorspace.js");
 
-var _stream = require("./stream.js");
-
 var _glyphlist = require("./glyphlist.js");
 
+var _core_utils = require("./core_utils.js");
+
 var _metrics = require("./metrics.js");
 
 var _murmurhash = require("./murmurhash3.js");
@@ -258,10 +258,6 @@ class PartialEvaluator {
             try {
               graphicState = xref.fetch(graphicState);
             } catch (ex) {
-              if (ex instanceof _core_utils.MissingDataException) {
-                throw ex;
-              }
-
               processed.put(graphicState);
               (0, _util.info)(`hasBlendModes - ignoring ExtGState: "${ex}".`);
               continue;
@@ -311,10 +307,6 @@ class PartialEvaluator {
           try {
             xObject = xref.fetch(xObject);
           } catch (ex) {
-            if (ex instanceof _core_utils.MissingDataException) {
-              throw ex;
-            }
-
             processed.put(xObject);
             (0, _util.info)(`hasBlendModes - ignoring XObject: "${ex}".`);
             continue;
@@ -578,6 +570,11 @@ class PartialEvaluator {
       localColorSpaceCache
     }).then(imageObj => {
       imgData = imageObj.createImageData(false);
+
+      if (cacheKey && imageRef && cacheGlobally) {
+        this.globalImageCache.addByteSize(imageRef, imgData.data.length);
+      }
+
       return this._sendImgData(objId, imgData, cacheGlobally);
     }).catch(reason => {
       (0, _util.warn)(`Unable to decode image "${objId}": "${reason}".`);
@@ -600,7 +597,8 @@ class PartialEvaluator {
           this.globalImageCache.setData(imageRef, {
             objId,
             fn: _util.OPS.paintImageXObject,
-            args
+            args,
+            byteSize: 0
           });
         }
       }
@@ -730,13 +728,7 @@ class PartialEvaluator {
   }
 
   handleSetFont(resources, fontArgs, fontRef, operatorList, task, state, fallbackFontDict = null) {
-    var fontName;
-
-    if (fontArgs) {
-      fontArgs = fontArgs.slice();
-      fontName = fontArgs[0].name;
-    }
-
+    const fontName = fontArgs && fontArgs[0] instanceof _primitives.Name ? fontArgs[0].name : null;
     return this.loadFont(fontName, fontRef, resources, fallbackFontDict).then(translated => {
       if (!translated.font.isType3Font) {
         return translated;
@@ -969,7 +961,7 @@ class PartialEvaluator {
     try {
       preEvaluatedFont = this.preEvaluateFont(font);
     } catch (reason) {
-      (0, _util.warn)(`loadFont - ignoring preEvaluateFont errors: "${reason}".`);
+      (0, _util.warn)(`loadFont - preEvaluateFont failed: "${reason}".`);
       return errorFont();
     }
 
@@ -1040,6 +1032,7 @@ class PartialEvaluator {
       this.handler.send("UnsupportedFeature", {
         featureId: _util.UNSUPPORTED_FEATURES.errorFontTranslate
       });
+      (0, _util.warn)(`loadFont - translateFont failed: "${reason}".`);
 
       try {
         var fontFile3 = descriptor && descriptor.get("FontFile3");
@@ -1125,11 +1118,7 @@ class PartialEvaluator {
           const tilingPatternIR = (0, _pattern.getTilingPatternIR)(localTilingPattern.operatorListIR, localTilingPattern.dict, color);
           operatorList.addOp(fn, tilingPatternIR);
           return undefined;
-        } catch (ex) {
-          if (ex instanceof _core_utils.MissingDataException) {
-            throw ex;
-          }
-        }
+        } catch (ex) {}
       }
 
       let pattern = patterns.get(name);
@@ -1766,7 +1755,7 @@ class PartialEvaluator {
     normalizeWhitespace = false,
     combineTextItems = false,
     sink,
-    seenStyles = Object.create(null)
+    seenStyles = new Set()
   }) {
     resources = resources || _primitives.Dict.empty;
     stateManager = stateManager || new StateManager(new TextState());
@@ -1808,11 +1797,12 @@ class PartialEvaluator {
         return textContentItem;
       }
 
-      var font = textState.font;
+      const font = textState.font,
+            loadedName = font.loadedName;
 
-      if (!(font.loadedName in seenStyles)) {
-        seenStyles[font.loadedName] = true;
-        textContent.styles[font.loadedName] = {
+      if (!seenStyles.has(loadedName)) {
+        seenStyles.add(loadedName);
+        textContent.styles[loadedName] = {
           fontFamily: font.fallbackName,
           ascent: font.ascent,
           descent: font.descent,
@@ -1820,7 +1810,7 @@ class PartialEvaluator {
         };
       }
 
-      textContentItem.fontName = font.loadedName;
+      textContentItem.fontName = loadedName;
       var tsm = [textState.fontSize * textState.textHScale, 0, 0, textState.fontSize, 0, textState.textRise];
 
       if (font.isType3Font && textState.fontSize <= 1 && !(0, _util.isArrayEqual)(textState.fontMatrix, _util.FONT_IDENTITY_MATRIX)) {
@@ -1837,20 +1827,16 @@ class PartialEvaluator {
 
       if (!font.vertical) {
         textContentItem.width = 0;
-        textContentItem.height = Math.sqrt(trm[2] * trm[2] + trm[3] * trm[3]);
+        textContentItem.height = Math.hypot(trm[2], trm[3]);
         textContentItem.vertical = false;
       } else {
-        textContentItem.width = Math.sqrt(trm[0] * trm[0] + trm[1] * trm[1]);
+        textContentItem.width = Math.hypot(trm[0], trm[1]);
         textContentItem.height = 0;
         textContentItem.vertical = true;
       }
 
-      var a = textState.textLineMatrix[0];
-      var b = textState.textLineMatrix[1];
-      var scaleLineX = Math.sqrt(a * a + b * b);
-      a = textState.ctm[0];
-      b = textState.ctm[1];
-      var scaleCtmX = Math.sqrt(a * a + b * b);
+      const scaleLineX = Math.hypot(textState.textLineMatrix[0], textState.textLineMatrix[1]);
+      const scaleCtmX = Math.hypot(textState.ctm[0], textState.ctm[1]);
       textContentItem.textAdvanceScale = scaleCtmX * scaleLineX;
       textContentItem.lastAdvanceWidth = 0;
       textContentItem.lastAdvanceHeight = 0;
@@ -2241,6 +2227,13 @@ class PartialEvaluator {
                   return;
                 }
 
+                const globalImage = self.globalImageCache.getData(xobj, self.pageIndex);
+
+                if (globalImage) {
+                  resolveXObject();
+                  return;
+                }
+
                 xobj = xref.fetch(xobj);
               }
 
@@ -2839,7 +2832,7 @@ class PartialEvaluator {
 
   getBaseFontMetrics(name) {
     var defaultWidth = 0;
-    var widths = [];
+    var widths = Object.create(null);
     var monospace = false;
     var stdFontMap = (0, _standard_fonts.getStdFontMap)();
     var lookupName = stdFontMap[name] || name;
@@ -3074,7 +3067,18 @@ class PartialEvaluator {
       throw new _util.FormatError("invalid font name");
     }
 
-    var fontFile = descriptor.get("FontFile", "FontFile2", "FontFile3");
+    let fontFile;
+
+    try {
+      fontFile = descriptor.get("FontFile", "FontFile2", "FontFile3");
+    } catch (ex) {
+      if (!this.options.ignoreErrors) {
+        throw ex;
+      }
+
+      (0, _util.warn)(`translateFont - fetching "${fontName.name}" font file: "${ex}".`);
+      fontFile = new _stream.NullStream();
+    }
 
     if (fontFile) {
       if (fontFile.dict) {

+ 59 - 59
lib/core/font_renderer.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ var _encodings = require("./encodings.js");
 
 var _stream = require("./stream.js");
 
-var FontRendererFactory = function FontRendererFactoryClosure() {
+const FontRendererFactory = function FontRendererFactoryClosure() {
   function getLong(data, offset) {
     return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];
   }
@@ -59,13 +59,13 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
   }
 
   function parseCmap(data, start, end) {
-    var offset = getUshort(data, start + 2) === 1 ? getLong(data, start + 8) : getLong(data, start + 16);
-    var format = getUshort(data, start + offset);
-    var ranges, p, i;
+    const offset = getUshort(data, start + 2) === 1 ? getLong(data, start + 8) : getLong(data, start + 16);
+    const format = getUshort(data, start + offset);
+    let ranges, p, i;
 
     if (format === 4) {
       getUshort(data, start + offset + 2);
-      var segCount = getUshort(data, start + offset + 6) >> 1;
+      const segCount = getUshort(data, start + offset + 6) >> 1;
       p = start + offset + 14;
       ranges = [];
 
@@ -86,7 +86,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
       }
 
       for (i = 0; i < segCount; i++, p += 2) {
-        var idOffset = getUshort(data, p);
+        let idOffset = getUshort(data, p);
 
         if (idOffset === 0) {
           continue;
@@ -94,7 +94,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
 
         ranges[i].ids = [];
 
-        for (var j = 0, jj = ranges[i].end - ranges[i].start + 1; j < jj; j++) {
+        for (let j = 0, jj = ranges[i].end - ranges[i].start + 1; j < jj; j++) {
           ranges[i].ids[j] = getUshort(data, p + idOffset);
           idOffset += 2;
         }
@@ -103,7 +103,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
       return ranges;
     } else if (format === 12) {
       getLong(data, start + offset + 4);
-      var groups = getLong(data, start + offset + 12);
+      const groups = getLong(data, start + offset + 12);
       p = start + offset + 16;
       ranges = [];
 
@@ -123,9 +123,9 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
   }
 
   function parseCff(data, start, end, seacAnalysisEnabled) {
-    var properties = {};
-    var parser = new _cff_parser.CFFParser(new _stream.Stream(data, start, end - start), properties, seacAnalysisEnabled);
-    var cff = parser.parse();
+    const properties = {};
+    const parser = new _cff_parser.CFFParser(new _stream.Stream(data, start, end - start), properties, seacAnalysisEnabled);
+    const cff = parser.parse();
     return {
       glyphs: cff.charStrings.objects,
       subrs: cff.topDict.privateDict && cff.topDict.privateDict.subrsIndex && cff.topDict.privateDict.subrsIndex.objects,
@@ -137,7 +137,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
   }
 
   function parseGlyfTable(glyf, loca, isGlyphLocationsLong) {
-    var itemSize, itemDecode;
+    let itemSize, itemDecode;
 
     if (isGlyphLocationsLong) {
       itemSize = 4;
@@ -153,11 +153,11 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
       };
     }
 
-    var glyphs = [];
-    var startOffset = itemDecode(loca, 0);
+    const glyphs = [];
+    let startOffset = itemDecode(loca, 0);
 
-    for (var j = itemSize; j < loca.length; j += itemSize) {
-      var endOffset = itemDecode(loca, j);
+    for (let j = itemSize; j < loca.length; j += itemSize) {
+      const endOffset = itemDecode(loca, j);
       glyphs.push(glyf.subarray(startOffset, endOffset));
       startOffset = endOffset;
     }
@@ -166,13 +166,13 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
   }
 
   function lookupCmap(ranges, unicode) {
-    var code = unicode.codePointAt(0),
-        gid = 0;
-    var l = 0,
+    const code = unicode.codePointAt(0);
+    let gid = 0,
+        l = 0,
         r = ranges.length - 1;
 
     while (l < r) {
-      var c = l + r + 1 >> 1;
+      const c = l + r + 1 >> 1;
 
       if (code < ranges[c].start) {
         r = c - 1;
@@ -213,19 +213,19 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
       });
     }
 
-    var i = 0;
-    var numberOfContours = (code[i] << 24 | code[i + 1] << 16) >> 16;
-    var flags;
-    var x = 0,
+    let i = 0;
+    const numberOfContours = (code[i] << 24 | code[i + 1] << 16) >> 16;
+    let flags;
+    let x = 0,
         y = 0;
     i += 10;
 
     if (numberOfContours < 0) {
       do {
         flags = code[i] << 8 | code[i + 1];
-        var glyphIndex = code[i + 2] << 8 | code[i + 3];
+        const glyphIndex = code[i + 2] << 8 | code[i + 3];
         i += 4;
-        var arg1, arg2;
+        let arg1, arg2;
 
         if (flags & 0x01) {
           arg1 = (code[i] << 24 | code[i + 1] << 16) >> 16;
@@ -244,7 +244,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
           y = 0;
         }
 
-        var scaleX = 1,
+        let scaleX = 1,
             scaleY = 1,
             scale01 = 0,
             scale10 = 0;
@@ -264,7 +264,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
           i += 8;
         }
 
-        var subglyph = font.glyphs[glyphIndex];
+        const subglyph = font.glyphs[glyphIndex];
 
         if (subglyph) {
           cmds.push({
@@ -281,22 +281,22 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
         }
       } while (flags & 0x20);
     } else {
-      var endPtsOfContours = [];
-      var j, jj;
+      const endPtsOfContours = [];
+      let j, jj;
 
       for (j = 0; j < numberOfContours; j++) {
         endPtsOfContours.push(code[i] << 8 | code[i + 1]);
         i += 2;
       }
 
-      var instructionLength = code[i] << 8 | code[i + 1];
+      const instructionLength = code[i] << 8 | code[i + 1];
       i += 2 + instructionLength;
-      var numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1;
-      var points = [];
+      const numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1;
+      const points = [];
 
       while (points.length < numberOfPoints) {
         flags = code[i++];
-        var repeat = 1;
+        let repeat = 1;
 
         if (flags & 0x08) {
           repeat += code[i++];
@@ -347,18 +347,18 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
         points[j].y = y;
       }
 
-      var startPoint = 0;
+      let startPoint = 0;
 
       for (i = 0; i < numberOfContours; i++) {
-        var endPoint = endPtsOfContours[i];
-        var contour = points.slice(startPoint, endPoint + 1);
+        const endPoint = endPtsOfContours[i];
+        const contour = points.slice(startPoint, endPoint + 1);
 
         if (contour[0].flags & 1) {
           contour.push(contour[0]);
         } else if (contour[contour.length - 1].flags & 1) {
           contour.unshift(contour[contour.length - 1]);
         } else {
-          var p = {
+          const p = {
             flags: 1,
             x: (contour[0].x + contour[contour.length - 1].x) / 2,
             y: (contour[0].y + contour[contour.length - 1].y) / 2
@@ -407,18 +407,18 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
       });
     }
 
-    var stack = [];
-    var x = 0,
+    const stack = [];
+    let x = 0,
         y = 0;
-    var stems = 0;
+    let stems = 0;
 
     function parse(code) {
-      var i = 0;
+      let i = 0;
 
       while (i < code.length) {
-        var stackClean = false;
-        var v = code[i++];
-        var xa, xb, ya, yb, y1, y2, y3, n, subrCode;
+        let stackClean = false;
+        let v = code[i++];
+        let xa, xb, ya, yb, y1, y2, y3, n, subrCode;
 
         switch (v) {
           case 1:
@@ -573,8 +573,8 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
                 break;
 
               case 37:
-                var x0 = x,
-                    y0 = y;
+                const x0 = x,
+                      y0 = y;
                 xa = x + stack.shift();
                 ya = y + stack.shift();
                 xb = xa + stack.shift();
@@ -606,8 +606,8 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
 
           case 14:
             if (stack.length >= 4) {
-              var achar = stack.pop();
-              var bchar = stack.pop();
+              const achar = stack.pop();
+              const bchar = stack.pop();
               y = stack.pop();
               x = stack.pop();
               cmds.push({
@@ -617,7 +617,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
                 cmd: "translate",
                 args: [x, y]
               });
-              var cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[_encodings.StandardEncoding[achar]]));
+              let cmap = lookupCmap(font.cmap, String.fromCharCode(font.glyphNameMap[_encodings.StandardEncoding[achar]]));
               compileCharString(font.glyphs[cmap.glyphId], cmds, font, cmap.glyphId);
               cmds.push({
                 cmd: "restore"
@@ -935,14 +935,14 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
 
   return {
     create: function FontRendererFactory_create(font, seacAnalysisEnabled) {
-      var data = new Uint8Array(font.data);
-      var cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;
-      var numTables = getUshort(data, 4);
+      const data = new Uint8Array(font.data);
+      let cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;
+      const numTables = getUshort(data, 4);
 
-      for (var i = 0, p = 12; i < numTables; i++, p += 16) {
-        var tag = (0, _util.bytesToString)(data.subarray(p, p + 4));
-        var offset = getLong(data, p + 8);
-        var length = getLong(data, p + 12);
+      for (let i = 0, p = 12; i < numTables; i++, p += 16) {
+        const tag = (0, _util.bytesToString)(data.subarray(p, p + 4));
+        const offset = getLong(data, p + 8);
+        const length = getLong(data, p + 12);
 
         switch (tag) {
           case "cmap":
@@ -969,7 +969,7 @@ var FontRendererFactory = function FontRendererFactoryClosure() {
       }
 
       if (glyf) {
-        var fontMatrix = !unitsPerEm ? font.fontMatrix : [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0];
+        const fontMatrix = !unitsPerEm ? font.fontMatrix : [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0];
         return new TrueTypeCompiled(parseGlyfTable(glyf, loca, indexToLocFormat), cmap, fontMatrix);
       }
 

+ 15 - 8
lib/core/fonts.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -2425,15 +2425,22 @@ var Font = function FontClosure() {
           }
         }
 
-        if (properties.glyphNames && baseEncoding.length) {
+        if (properties.glyphNames && (baseEncoding.length || this.differences.length)) {
           for (let i = 0; i < 256; ++i) {
-            if (charCodeToGlyphId[i] === undefined && baseEncoding[i]) {
-              glyphName = baseEncoding[i];
-              const glyphId = properties.glyphNames.indexOf(glyphName);
+            if (charCodeToGlyphId[i] !== undefined) {
+              continue;
+            }
 
-              if (glyphId > 0 && hasGlyph(glyphId)) {
-                charCodeToGlyphId[i] = glyphId;
-              }
+            glyphName = this.differences[i] || baseEncoding[i];
+
+            if (!glyphName) {
+              continue;
+            }
+
+            const glyphId = properties.glyphNames.indexOf(glyphName);
+
+            if (glyphId > 0 && hasGlyph(glyphId)) {
+              charCodeToGlyphId[i] = glyphId;
             }
           }
         }

+ 366 - 353
lib/core/function.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -670,26 +670,28 @@ function isPDFFunction(v) {
 var PostScriptStack = function PostScriptStackClosure() {
   var MAX_STACK_SIZE = 100;
 
-  function PostScriptStack(initialStack) {
-    this.stack = !initialStack ? [] : Array.prototype.slice.call(initialStack, 0);
-  }
+  class PostScriptStack {
+    constructor(initialStack) {
+      this.stack = !initialStack ? [] : Array.prototype.slice.call(initialStack, 0);
+    }
 
-  PostScriptStack.prototype = {
-    push: function PostScriptStack_push(value) {
+    push(value) {
       if (this.stack.length >= MAX_STACK_SIZE) {
         throw new Error("PostScript function stack overflow.");
       }
 
       this.stack.push(value);
-    },
-    pop: function PostScriptStack_pop() {
+    }
+
+    pop() {
       if (this.stack.length <= 0) {
         throw new Error("PostScript function stack underflow.");
       }
 
       return this.stack.pop();
-    },
-    copy: function PostScriptStack_copy(n) {
+    }
+
+    copy(n) {
       if (this.stack.length + n >= MAX_STACK_SIZE) {
         throw new Error("PostScript function stack overflow.");
       }
@@ -699,11 +701,13 @@ var PostScriptStack = function PostScriptStackClosure() {
       for (var i = stack.length - n, j = n - 1; j >= 0; j--, i++) {
         stack.push(stack[i]);
       }
-    },
-    index: function PostScriptStack_index(n) {
+    }
+
+    index(n) {
       this.push(this.stack[this.stack.length - n - 1]);
-    },
-    roll: function PostScriptStack_roll(n, p) {
+    }
+
+    roll(n, p) {
       var stack = this.stack;
       var l = stack.length - n;
       var r = stack.length - 1,
@@ -730,406 +734,415 @@ var PostScriptStack = function PostScriptStackClosure() {
         stack[j] = t;
       }
     }
-  };
+
+  }
+
   return PostScriptStack;
 }();
 
-var PostScriptEvaluator = function PostScriptEvaluatorClosure() {
-  function PostScriptEvaluator(operators) {
+class PostScriptEvaluator {
+  constructor(operators) {
     this.operators = operators;
   }
 
-  PostScriptEvaluator.prototype = {
-    execute: function PostScriptEvaluator_execute(initialStack) {
-      var stack = new PostScriptStack(initialStack);
-      var counter = 0;
-      var operators = this.operators;
-      var length = operators.length;
-      var operator, a, b;
-
-      while (counter < length) {
-        operator = operators[counter++];
-
-        if (typeof operator === "number") {
-          stack.push(operator);
-          continue;
-        }
-
-        switch (operator) {
-          case "jz":
-            b = stack.pop();
-            a = stack.pop();
-
-            if (!a) {
-              counter = b;
-            }
-
-            break;
-
-          case "j":
-            a = stack.pop();
-            counter = a;
-            break;
-
-          case "abs":
-            a = stack.pop();
-            stack.push(Math.abs(a));
-            break;
-
-          case "add":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a + b);
-            break;
-
-          case "and":
-            b = stack.pop();
-            a = stack.pop();
-
-            if ((0, _util.isBool)(a) && (0, _util.isBool)(b)) {
-              stack.push(a && b);
-            } else {
-              stack.push(a & b);
-            }
-
-            break;
-
-          case "atan":
-            a = stack.pop();
-            stack.push(Math.atan(a));
-            break;
-
-          case "bitshift":
-            b = stack.pop();
-            a = stack.pop();
-
-            if (a > 0) {
-              stack.push(a << b);
-            } else {
-              stack.push(a >> b);
-            }
-
-            break;
-
-          case "ceiling":
-            a = stack.pop();
-            stack.push(Math.ceil(a));
-            break;
-
-          case "copy":
-            a = stack.pop();
-            stack.copy(a);
-            break;
-
-          case "cos":
-            a = stack.pop();
-            stack.push(Math.cos(a));
-            break;
-
-          case "cvi":
-            a = stack.pop() | 0;
-            stack.push(a);
-            break;
+  execute(initialStack) {
+    var stack = new PostScriptStack(initialStack);
+    var counter = 0;
+    var operators = this.operators;
+    var length = operators.length;
+    var operator, a, b;
 
-          case "cvr":
-            break;
+    while (counter < length) {
+      operator = operators[counter++];
 
-          case "div":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a / b);
-            break;
+      if (typeof operator === "number") {
+        stack.push(operator);
+        continue;
+      }
 
-          case "dup":
-            stack.copy(1);
-            break;
+      switch (operator) {
+        case "jz":
+          b = stack.pop();
+          a = stack.pop();
 
-          case "eq":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a === b);
-            break;
+          if (!a) {
+            counter = b;
+          }
 
-          case "exch":
-            stack.roll(2, 1);
-            break;
+          break;
 
-          case "exp":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a ** b);
-            break;
+        case "j":
+          a = stack.pop();
+          counter = a;
+          break;
 
-          case "false":
-            stack.push(false);
-            break;
+        case "abs":
+          a = stack.pop();
+          stack.push(Math.abs(a));
+          break;
 
-          case "floor":
-            a = stack.pop();
-            stack.push(Math.floor(a));
-            break;
+        case "add":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a + b);
+          break;
 
-          case "ge":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a >= b);
-            break;
+        case "and":
+          b = stack.pop();
+          a = stack.pop();
 
-          case "gt":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a > b);
-            break;
+          if ((0, _util.isBool)(a) && (0, _util.isBool)(b)) {
+            stack.push(a && b);
+          } else {
+            stack.push(a & b);
+          }
 
-          case "idiv":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a / b | 0);
-            break;
+          break;
 
-          case "index":
-            a = stack.pop();
-            stack.index(a);
-            break;
+        case "atan":
+          a = stack.pop();
+          stack.push(Math.atan(a));
+          break;
 
-          case "le":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a <= b);
-            break;
+        case "bitshift":
+          b = stack.pop();
+          a = stack.pop();
 
-          case "ln":
-            a = stack.pop();
-            stack.push(Math.log(a));
-            break;
+          if (a > 0) {
+            stack.push(a << b);
+          } else {
+            stack.push(a >> b);
+          }
 
-          case "log":
-            a = stack.pop();
-            stack.push(Math.log(a) / Math.LN10);
-            break;
+          break;
+
+        case "ceiling":
+          a = stack.pop();
+          stack.push(Math.ceil(a));
+          break;
+
+        case "copy":
+          a = stack.pop();
+          stack.copy(a);
+          break;
+
+        case "cos":
+          a = stack.pop();
+          stack.push(Math.cos(a));
+          break;
+
+        case "cvi":
+          a = stack.pop() | 0;
+          stack.push(a);
+          break;
+
+        case "cvr":
+          break;
+
+        case "div":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a / b);
+          break;
+
+        case "dup":
+          stack.copy(1);
+          break;
+
+        case "eq":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a === b);
+          break;
+
+        case "exch":
+          stack.roll(2, 1);
+          break;
+
+        case "exp":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a ** b);
+          break;
+
+        case "false":
+          stack.push(false);
+          break;
+
+        case "floor":
+          a = stack.pop();
+          stack.push(Math.floor(a));
+          break;
+
+        case "ge":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a >= b);
+          break;
+
+        case "gt":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a > b);
+          break;
+
+        case "idiv":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a / b | 0);
+          break;
+
+        case "index":
+          a = stack.pop();
+          stack.index(a);
+          break;
+
+        case "le":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a <= b);
+          break;
+
+        case "ln":
+          a = stack.pop();
+          stack.push(Math.log(a));
+          break;
+
+        case "log":
+          a = stack.pop();
+          stack.push(Math.log(a) / Math.LN10);
+          break;
+
+        case "lt":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a < b);
+          break;
+
+        case "mod":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a % b);
+          break;
+
+        case "mul":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a * b);
+          break;
+
+        case "ne":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a !== b);
+          break;
+
+        case "neg":
+          a = stack.pop();
+          stack.push(-a);
+          break;
+
+        case "not":
+          a = stack.pop();
+
+          if ((0, _util.isBool)(a)) {
+            stack.push(!a);
+          } else {
+            stack.push(~a);
+          }
 
-          case "lt":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a < b);
-            break;
+          break;
 
-          case "mod":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a % b);
-            break;
+        case "or":
+          b = stack.pop();
+          a = stack.pop();
 
-          case "mul":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a * b);
-            break;
+          if ((0, _util.isBool)(a) && (0, _util.isBool)(b)) {
+            stack.push(a || b);
+          } else {
+            stack.push(a | b);
+          }
 
-          case "ne":
-            b = stack.pop();
-            a = stack.pop();
+          break;
+
+        case "pop":
+          stack.pop();
+          break;
+
+        case "roll":
+          b = stack.pop();
+          a = stack.pop();
+          stack.roll(a, b);
+          break;
+
+        case "round":
+          a = stack.pop();
+          stack.push(Math.round(a));
+          break;
+
+        case "sin":
+          a = stack.pop();
+          stack.push(Math.sin(a));
+          break;
+
+        case "sqrt":
+          a = stack.pop();
+          stack.push(Math.sqrt(a));
+          break;
+
+        case "sub":
+          b = stack.pop();
+          a = stack.pop();
+          stack.push(a - b);
+          break;
+
+        case "true":
+          stack.push(true);
+          break;
+
+        case "truncate":
+          a = stack.pop();
+          a = a < 0 ? Math.ceil(a) : Math.floor(a);
+          stack.push(a);
+          break;
+
+        case "xor":
+          b = stack.pop();
+          a = stack.pop();
+
+          if ((0, _util.isBool)(a) && (0, _util.isBool)(b)) {
             stack.push(a !== b);
-            break;
-
-          case "neg":
-            a = stack.pop();
-            stack.push(-a);
-            break;
-
-          case "not":
-            a = stack.pop();
-
-            if ((0, _util.isBool)(a)) {
-              stack.push(!a);
-            } else {
-              stack.push(~a);
-            }
-
-            break;
-
-          case "or":
-            b = stack.pop();
-            a = stack.pop();
-
-            if ((0, _util.isBool)(a) && (0, _util.isBool)(b)) {
-              stack.push(a || b);
-            } else {
-              stack.push(a | b);
-            }
-
-            break;
-
-          case "pop":
-            stack.pop();
-            break;
-
-          case "roll":
-            b = stack.pop();
-            a = stack.pop();
-            stack.roll(a, b);
-            break;
-
-          case "round":
-            a = stack.pop();
-            stack.push(Math.round(a));
-            break;
-
-          case "sin":
-            a = stack.pop();
-            stack.push(Math.sin(a));
-            break;
-
-          case "sqrt":
-            a = stack.pop();
-            stack.push(Math.sqrt(a));
-            break;
-
-          case "sub":
-            b = stack.pop();
-            a = stack.pop();
-            stack.push(a - b);
-            break;
-
-          case "true":
-            stack.push(true);
-            break;
-
-          case "truncate":
-            a = stack.pop();
-            a = a < 0 ? Math.ceil(a) : Math.floor(a);
-            stack.push(a);
-            break;
-
-          case "xor":
-            b = stack.pop();
-            a = stack.pop();
-
-            if ((0, _util.isBool)(a) && (0, _util.isBool)(b)) {
-              stack.push(a !== b);
-            } else {
-              stack.push(a ^ b);
-            }
+          } else {
+            stack.push(a ^ b);
+          }
 
-            break;
+          break;
 
-          default:
-            throw new _util.FormatError(`Unknown operator ${operator}`);
-        }
+        default:
+          throw new _util.FormatError(`Unknown operator ${operator}`);
       }
-
-      return stack.stack;
     }
-  };
-  return PostScriptEvaluator;
-}();
+
+    return stack.stack;
+  }
+
+}
 
 exports.PostScriptEvaluator = PostScriptEvaluator;
 
 var PostScriptCompiler = function PostScriptCompilerClosure() {
-  function AstNode(type) {
-    this.type = type;
-  }
+  class AstNode {
+    constructor(type) {
+      this.type = type;
+    }
 
-  AstNode.prototype.visit = function (visitor) {
-    (0, _util.unreachable)("abstract method");
-  };
+    visit(visitor) {
+      (0, _util.unreachable)("abstract method");
+    }
 
-  function AstArgument(index, min, max) {
-    AstNode.call(this, "args");
-    this.index = index;
-    this.min = min;
-    this.max = max;
   }
 
-  AstArgument.prototype = Object.create(AstNode.prototype);
+  class AstArgument extends AstNode {
+    constructor(index, min, max) {
+      super("args");
+      this.index = index;
+      this.min = min;
+      this.max = max;
+    }
 
-  AstArgument.prototype.visit = function (visitor) {
-    visitor.visitArgument(this);
-  };
+    visit(visitor) {
+      visitor.visitArgument(this);
+    }
 
-  function AstLiteral(number) {
-    AstNode.call(this, "literal");
-    this.number = number;
-    this.min = number;
-    this.max = number;
   }
 
-  AstLiteral.prototype = Object.create(AstNode.prototype);
+  class AstLiteral extends AstNode {
+    constructor(number) {
+      super("literal");
+      this.number = number;
+      this.min = number;
+      this.max = number;
+    }
 
-  AstLiteral.prototype.visit = function (visitor) {
-    visitor.visitLiteral(this);
-  };
+    visit(visitor) {
+      visitor.visitLiteral(this);
+    }
 
-  function AstBinaryOperation(op, arg1, arg2, min, max) {
-    AstNode.call(this, "binary");
-    this.op = op;
-    this.arg1 = arg1;
-    this.arg2 = arg2;
-    this.min = min;
-    this.max = max;
   }
 
-  AstBinaryOperation.prototype = Object.create(AstNode.prototype);
+  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;
+    }
 
-  AstBinaryOperation.prototype.visit = function (visitor) {
-    visitor.visitBinaryOperation(this);
-  };
+    visit(visitor) {
+      visitor.visitBinaryOperation(this);
+    }
 
-  function AstMin(arg, max) {
-    AstNode.call(this, "max");
-    this.arg = arg;
-    this.min = arg.min;
-    this.max = max;
   }
 
-  AstMin.prototype = Object.create(AstNode.prototype);
+  class AstMin extends AstNode {
+    constructor(arg, max) {
+      super("max");
+      this.arg = arg;
+      this.min = arg.min;
+      this.max = max;
+    }
 
-  AstMin.prototype.visit = function (visitor) {
-    visitor.visitMin(this);
-  };
+    visit(visitor) {
+      visitor.visitMin(this);
+    }
 
-  function AstVariable(index, min, max) {
-    AstNode.call(this, "var");
-    this.index = index;
-    this.min = min;
-    this.max = max;
   }
 
-  AstVariable.prototype = Object.create(AstNode.prototype);
+  class AstVariable extends AstNode {
+    constructor(index, min, max) {
+      super("var");
+      this.index = index;
+      this.min = min;
+      this.max = max;
+    }
 
-  AstVariable.prototype.visit = function (visitor) {
-    visitor.visitVariable(this);
-  };
+    visit(visitor) {
+      visitor.visitVariable(this);
+    }
 
-  function AstVariableDefinition(variable, arg) {
-    AstNode.call(this, "definition");
-    this.variable = variable;
-    this.arg = arg;
   }
 
-  AstVariableDefinition.prototype = Object.create(AstNode.prototype);
+  class AstVariableDefinition extends AstNode {
+    constructor(variable, arg) {
+      super("definition");
+      this.variable = variable;
+      this.arg = arg;
+    }
 
-  AstVariableDefinition.prototype.visit = function (visitor) {
-    visitor.visitVariableDefinition(this);
-  };
+    visit(visitor) {
+      visitor.visitVariableDefinition(this);
+    }
 
-  function ExpressionBuilderVisitor() {
-    this.parts = [];
   }
 
-  ExpressionBuilderVisitor.prototype = {
+  class ExpressionBuilderVisitor {
+    constructor() {
+      this.parts = [];
+    }
+
     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);
-    },
+    }
 
     visitLiteral(literal) {
       this.parts.push(literal.number);
-    },
+    }
 
     visitBinaryOperation(operation) {
       this.parts.push("(");
@@ -1137,7 +1150,7 @@ var PostScriptCompiler = function PostScriptCompilerClosure() {
       this.parts.push(" ", operation.op, " ");
       operation.arg2.visit(this);
       this.parts.push(")");
-    },
+    }
 
     visitVariableDefinition(definition) {
       this.parts.push("var ");
@@ -1145,19 +1158,19 @@ var PostScriptCompiler = function PostScriptCompilerClosure() {
       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, ")");
-    },
+    }
 
     toString() {
       return this.parts.join("");
     }
 
-  };
+  }
 
   function buildAddOperation(num1, num2) {
     if (num2.type === "literal" && num2.number === 0) {
@@ -1225,10 +1238,8 @@ var PostScriptCompiler = function PostScriptCompilerClosure() {
     return new AstMin(num1, max);
   }
 
-  function PostScriptCompiler() {}
-
-  PostScriptCompiler.prototype = {
-    compile: function PostScriptCompiler_compile(code, domain, range) {
+  class PostScriptCompiler {
+    compile(code, domain, range) {
       var stack = [];
       var instructions = [];
       var inputSize = domain.length >> 1,
@@ -1426,7 +1437,9 @@ var PostScriptCompiler = function PostScriptCompilerClosure() {
       });
       return result.join("\n");
     }
-  };
+
+  }
+
   return PostScriptCompiler;
 }();
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 2
lib/core/glyphlist.js


+ 1 - 1
lib/core/image.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 50 - 8
lib/core/image_utils.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -214,8 +214,12 @@ class GlobalImageCache {
     return (0, _util.shadow)(this, "NUM_PAGES_THRESHOLD", 2);
   }
 
-  static get MAX_IMAGES_TO_CACHE() {
-    return (0, _util.shadow)(this, "MAX_IMAGES_TO_CACHE", 10);
+  static get MIN_IMAGES_TO_CACHE() {
+    return (0, _util.shadow)(this, "MIN_IMAGES_TO_CACHE", 10);
+  }
+
+  static get MAX_BYTE_SIZE() {
+    return (0, _util.shadow)(this, "MAX_BYTE_SIZE", 40e6);
   }
 
   constructor() {
@@ -223,6 +227,28 @@ class GlobalImageCache {
     this._imageCache = new _primitives.RefSetCache();
   }
 
+  get _byteSize() {
+    let byteSize = 0;
+
+    this._imageCache.forEach(imageData => {
+      byteSize += imageData.byteSize;
+    });
+
+    return byteSize;
+  }
+
+  get _cacheLimitReached() {
+    if (this._imageCache.size < GlobalImageCache.MIN_IMAGES_TO_CACHE) {
+      return false;
+    }
+
+    if (this._byteSize < GlobalImageCache.MAX_BYTE_SIZE) {
+      return false;
+    }
+
+    return true;
+  }
+
   shouldCache(ref, pageIndex) {
     const pageIndexSet = this._refCache.get(ref);
 
@@ -232,7 +258,7 @@ class GlobalImageCache {
       return false;
     }
 
-    if (!this._imageCache.has(ref) && this._imageCache.size >= GlobalImageCache.MAX_IMAGES_TO_CACHE) {
+    if (!this._imageCache.has(ref) && this._cacheLimitReached) {
       return false;
     }
 
@@ -251,6 +277,20 @@ class GlobalImageCache {
     pageIndexSet.add(pageIndex);
   }
 
+  addByteSize(ref, byteSize) {
+    const imageData = this._imageCache.get(ref);
+
+    if (!imageData) {
+      return;
+    }
+
+    if (imageData.byteSize) {
+      return;
+    }
+
+    imageData.byteSize = byteSize;
+  }
+
   getData(ref, pageIndex) {
     const pageIndexSet = this._refCache.get(ref);
 
@@ -262,12 +302,14 @@ class GlobalImageCache {
       return null;
     }
 
-    if (!this._imageCache.has(ref)) {
+    const imageData = this._imageCache.get(ref);
+
+    if (!imageData) {
       return null;
     }
 
     pageIndexSet.add(pageIndex);
-    return this._imageCache.get(ref);
+    return imageData;
   }
 
   setData(ref, data) {
@@ -279,8 +321,8 @@ class GlobalImageCache {
       return;
     }
 
-    if (this._imageCache.size >= GlobalImageCache.MAX_IMAGES_TO_CACHE) {
-      (0, _util.info)("GlobalImageCache.setData - ignoring image above MAX_IMAGES_TO_CACHE.");
+    if (this._cacheLimitReached) {
+      (0, _util.warn)("GlobalImageCache.setData - cache limit reached.");
       return;
     }
 

+ 1 - 1
lib/core/jbig2.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
lib/core/jbig2_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
lib/core/jpeg_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
lib/core/jpg.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
lib/core/jpx.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
lib/core/jpx_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 155 - 0
lib/core/metadata_parser.js

@@ -0,0 +1,155 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * Javascript code in this page
+ *
+ * Copyright 2021 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.MetadataParser = void 0;
+
+var _xml_parser = require("./xml_parser.js");
+
+class MetadataParser {
+  constructor(data) {
+    data = this._repair(data);
+    const parser = new _xml_parser.SimpleXMLParser({
+      lowerCaseName: true
+    });
+    const xmlDocument = parser.parseFromString(data);
+    this._metadataMap = new Map();
+    this._data = data;
+
+    if (xmlDocument) {
+      this._parse(xmlDocument);
+    }
+  }
+
+  _repair(data) {
+    return data.replace(/^[^<]+/, "").replace(/>\\376\\377([^<]+)/g, function (all, codes) {
+      const bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g, function (code, d1, d2, d3) {
+        return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1);
+      }).replace(/&(amp|apos|gt|lt|quot);/g, function (str, name) {
+        switch (name) {
+          case "amp":
+            return "&";
+
+          case "apos":
+            return "'";
+
+          case "gt":
+            return ">";
+
+          case "lt":
+            return "<";
+
+          case "quot":
+            return '"';
+        }
+
+        throw new Error(`_repair: ${name} isn't defined.`);
+      });
+      const charBuf = [];
+
+      for (let i = 0, ii = bytes.length; i < ii; i += 2) {
+        const code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1);
+
+        if (code >= 32 && code < 127 && code !== 60 && code !== 62 && code !== 38) {
+          charBuf.push(String.fromCharCode(code));
+        } else {
+          charBuf.push("&#x" + (0x10000 + code).toString(16).substring(1) + ";");
+        }
+      }
+
+      return ">" + charBuf.join("");
+    });
+  }
+
+  _getSequence(entry) {
+    const name = entry.nodeName;
+
+    if (name !== "rdf:bag" && name !== "rdf:seq" && name !== "rdf:alt") {
+      return null;
+    }
+
+    return entry.childNodes.filter(node => node.nodeName === "rdf:li");
+  }
+
+  _parseArray(entry) {
+    if (!entry.hasChildNodes()) {
+      return;
+    }
+
+    const [seqNode] = entry.childNodes;
+    const sequence = this._getSequence(seqNode) || [];
+
+    this._metadataMap.set(entry.nodeName, sequence.map(node => node.textContent.trim()));
+  }
+
+  _parse(xmlDocument) {
+    let rdf = xmlDocument.documentElement;
+
+    if (rdf.nodeName !== "rdf:rdf") {
+      rdf = rdf.firstChild;
+
+      while (rdf && rdf.nodeName !== "rdf:rdf") {
+        rdf = rdf.nextSibling;
+      }
+    }
+
+    if (!rdf || rdf.nodeName !== "rdf:rdf" || !rdf.hasChildNodes()) {
+      return;
+    }
+
+    for (const desc of rdf.childNodes) {
+      if (desc.nodeName !== "rdf:description") {
+        continue;
+      }
+
+      for (const entry of desc.childNodes) {
+        const name = entry.nodeName;
+
+        switch (name) {
+          case "#text":
+            continue;
+
+          case "dc:creator":
+          case "dc:subject":
+            this._parseArray(entry);
+
+            continue;
+        }
+
+        this._metadataMap.set(name, entry.textContent.trim());
+      }
+    }
+  }
+
+  get serializable() {
+    return {
+      parsedData: this._metadataMap,
+      rawData: this._data
+    };
+  }
+
+}
+
+exports.MetadataParser = MetadataParser;

+ 2 - 2
lib/core/metrics.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ exports.getMetrics = void 0;
 
 var _core_utils = require("./core_utils.js");
 
-var getMetrics = (0, _core_utils.getLookupTableFactory)(function (t) {
+const getMetrics = (0, _core_utils.getLookupTableFactory)(function (t) {
   t.Courier = 600;
   t["Courier-Bold"] = 600;
   t["Courier-BoldOblique"] = 600;

+ 1 - 1
lib/core/murmurhash3.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 36 - 15
lib/core/obj.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,6 +40,8 @@ var _colorspace = require("./colorspace.js");
 
 var _image_utils = require("./image_utils.js");
 
+var _metadata_parser = require("./metadata_parser.js");
+
 function fetchDestination(dest) {
   return (0, _primitives.isDict)(dest) ? dest.get("D") : dest;
 }
@@ -120,15 +122,19 @@ class Catalog {
 
     const suppressEncryption = !(this.xref.encrypt && this.xref.encrypt.encryptMetadata);
     const stream = this.xref.fetch(streamRef, suppressEncryption);
-    let metadata;
+    let metadata = null;
 
-    if (stream && (0, _primitives.isDict)(stream.dict)) {
+    if ((0, _primitives.isStream)(stream) && (0, _primitives.isDict)(stream.dict)) {
       const type = stream.dict.get("Type");
       const subtype = stream.dict.get("Subtype");
 
       if ((0, _primitives.isName)(type, "Metadata") && (0, _primitives.isName)(subtype, "XML")) {
         try {
-          metadata = (0, _util.stringToUTF8String)((0, _util.bytesToString)(stream.getBytes()));
+          const data = (0, _util.stringToUTF8String)((0, _util.bytesToString)(stream.getBytes()));
+
+          if (data) {
+            metadata = new _metadata_parser.MetadataParser(data).serializable;
+          }
         } catch (e) {
           if (e instanceof _core_utils.MissingDataException) {
             throw e;
@@ -1388,7 +1394,11 @@ class Catalog {
           }
 
         default:
-          (0, _util.warn)(`parseDestDictionary: unsupported action type "${actionName}".`);
+          if (actionName === "JavaScript" || actionName === "ResetForm" || actionName === "SubmitForm") {
+            break;
+          }
+
+          (0, _util.warn)(`parseDestDictionary - unsupported action: "${actionName}".`);
           break;
       }
     } else if (destDict.has("Dest")) {
@@ -1894,10 +1904,6 @@ var XRef = function XRefClosure() {
             continue;
           }
         } catch (ex) {
-          if (ex instanceof _core_utils.MissingDataException) {
-            throw ex;
-          }
-
           continue;
         }
 
@@ -2117,12 +2123,13 @@ var XRef = function XRefClosure() {
         throw new _util.FormatError("invalid first and n parameters for ObjStm stream");
       }
 
-      const parser = new _parser.Parser({
+      let parser = new _parser.Parser({
         lexer: new _parser.Lexer(stream),
         xref: this,
         allowStreams: true
       });
       const nums = new Array(n);
+      const offsets = new Array(n);
 
       for (let i = 0; i < n; ++i) {
         const num = parser.getObj();
@@ -2138,18 +2145,27 @@ var XRef = function XRefClosure() {
         }
 
         nums[i] = num;
+        offsets[i] = offset;
       }
 
+      const start = (stream.start || 0) + first;
       const entries = new Array(n);
 
       for (let i = 0; i < n; ++i) {
-        const obj = parser.getObj();
-        entries[i] = obj;
+        const length = i < n - 1 ? offsets[i + 1] - offsets[i] : undefined;
 
-        if (parser.buf1 instanceof _primitives.Cmd && parser.buf1.cmd === "endobj") {
-          parser.shift();
+        if (length < 0) {
+          throw new _util.FormatError("Invalid offset in the ObjStm stream.");
         }
 
+        parser = new _parser.Parser({
+          lexer: new _parser.Lexer(stream.makeSubStream(start + offsets[i], length, stream.dict)),
+          xref: this,
+          allowStreams: true
+        });
+        const obj = parser.getObj();
+        entries[i] = obj;
+
         if ((0, _primitives.isStream)(obj)) {
           continue;
         }
@@ -2518,7 +2534,12 @@ const ObjectLoader = function () {
             currentNode = this.xref.fetch(currentNode);
           } catch (ex) {
             if (!(ex instanceof _core_utils.MissingDataException)) {
-              throw ex;
+              (0, _util.warn)(`ObjectLoader._walk - requesting all data: "${ex}".`);
+              this.refSet = null;
+              const {
+                manager
+              } = this.xref.stream;
+              return manager.requestAllChunks();
             }
 
             nodesToRevisit.push(currentNode);

+ 121 - 122
lib/core/operator_list.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,12 +28,12 @@ exports.OperatorList = void 0;
 
 var _util = require("../shared/util.js");
 
-var QueueOptimizer = function QueueOptimizerClosure() {
+const QueueOptimizer = function QueueOptimizerClosure() {
   function addState(parentState, pattern, checkFn, iterateFn, processFn) {
-    var state = parentState;
+    let state = parentState;
 
-    for (var i = 0, ii = pattern.length - 1; i < ii; i++) {
-      var item = pattern[i];
+    for (let i = 0, ii = pattern.length - 1; i < ii; i++) {
+      const item = pattern[i];
       state = state[item] || (state[item] = []);
     }
 
@@ -45,11 +45,12 @@ var QueueOptimizer = function QueueOptimizerClosure() {
   }
 
   function handlePaintSolidColorImageMask(iFirstSave, count, fnArray, argsArray) {
-    var iFirstPIMXO = iFirstSave + 2;
+    const iFirstPIMXO = iFirstSave + 2;
+    let i;
 
-    for (var i = 0; i < count; i++) {
-      var arg = argsArray[iFirstPIMXO + 4 * i];
-      var imageMask = arg.length === 1 && arg[0];
+    for (i = 0; i < count; i++) {
+      const arg = argsArray[iFirstPIMXO + 4 * i];
+      const imageMask = arg.length === 1 && arg[0];
 
       if (imageMask && imageMask.width === 1 && imageMask.height === 1 && (!imageMask.data.length || imageMask.data.length === 1 && imageMask.data[0] === 0)) {
         fnArray[iFirstPIMXO + 4 * i] = _util.OPS.paintSolidColorImageMask;
@@ -62,11 +63,11 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     return count - i;
   }
 
-  var InitialState = [];
+  const InitialState = [];
   addState(InitialState, [_util.OPS.save, _util.OPS.transform, _util.OPS.paintInlineImageXObject, _util.OPS.restore], null, function iterateInlineImageGroup(context, i) {
-    var fnArray = context.fnArray;
-    var iFirstSave = context.iCurr - 3;
-    var pos = (i - iFirstSave) % 4;
+    const fnArray = context.fnArray;
+    const iFirstSave = context.iCurr - 3;
+    const pos = (i - iFirstSave) % 4;
 
     switch (pos) {
       case 0:
@@ -84,32 +85,31 @@ var QueueOptimizer = function QueueOptimizerClosure() {
 
     throw new Error(`iterateInlineImageGroup - invalid pos: ${pos}`);
   }, function foundInlineImageGroup(context, i) {
-    var MIN_IMAGES_IN_INLINE_IMAGES_BLOCK = 10;
-    var MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200;
-    var MAX_WIDTH = 1000;
-    var IMAGE_PADDING = 1;
-    var fnArray = context.fnArray,
-        argsArray = context.argsArray;
-    var curr = context.iCurr;
-    var iFirstSave = curr - 3;
-    var iFirstTransform = curr - 2;
-    var iFirstPIIXO = curr - 1;
-    var count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_INLINE_IMAGES_BLOCK);
+    const MIN_IMAGES_IN_INLINE_IMAGES_BLOCK = 10;
+    const MAX_IMAGES_IN_INLINE_IMAGES_BLOCK = 200;
+    const MAX_WIDTH = 1000;
+    const IMAGE_PADDING = 1;
+    const fnArray = context.fnArray,
+          argsArray = context.argsArray;
+    const curr = context.iCurr;
+    const iFirstSave = curr - 3;
+    const iFirstTransform = curr - 2;
+    const iFirstPIIXO = curr - 1;
+    const count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_INLINE_IMAGES_BLOCK);
 
     if (count < MIN_IMAGES_IN_INLINE_IMAGES_BLOCK) {
       return i - (i - iFirstSave) % 4;
     }
 
-    var maxX = 0;
-    var map = [],
-        maxLineHeight = 0;
-    var currentX = IMAGE_PADDING,
+    let maxX = 0;
+    const map = [];
+    let maxLineHeight = 0;
+    let currentX = IMAGE_PADDING,
         currentY = IMAGE_PADDING;
-    var q;
 
-    for (q = 0; q < count; q++) {
-      var transform = argsArray[iFirstTransform + (q << 2)];
-      var img = argsArray[iFirstPIIXO + (q << 2)][0];
+    for (let q = 0; q < count; q++) {
+      const transform = argsArray[iFirstTransform + (q << 2)];
+      const img = argsArray[iFirstPIIXO + (q << 2)][0];
 
       if (currentX + img.width > MAX_WIDTH) {
         maxX = Math.max(maxX, currentX);
@@ -129,19 +129,19 @@ var QueueOptimizer = function QueueOptimizerClosure() {
       maxLineHeight = Math.max(maxLineHeight, img.height);
     }
 
-    var imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING;
-    var imgHeight = currentY + maxLineHeight + IMAGE_PADDING;
-    var imgData = new Uint8ClampedArray(imgWidth * imgHeight * 4);
-    var imgRowSize = imgWidth << 2;
+    const imgWidth = Math.max(maxX, currentX) + IMAGE_PADDING;
+    const imgHeight = currentY + maxLineHeight + IMAGE_PADDING;
+    const imgData = new Uint8ClampedArray(imgWidth * imgHeight * 4);
+    const imgRowSize = imgWidth << 2;
 
-    for (q = 0; q < count; q++) {
-      var data = argsArray[iFirstPIIXO + (q << 2)][0].data;
-      var rowSize = map[q].w << 2;
-      var dataOffset = 0;
-      var offset = map[q].x + map[q].y * imgWidth << 2;
+    for (let q = 0; q < count; q++) {
+      const data = argsArray[iFirstPIIXO + (q << 2)][0].data;
+      const rowSize = map[q].w << 2;
+      let dataOffset = 0;
+      let offset = map[q].x + map[q].y * imgWidth << 2;
       imgData.set(data.subarray(0, rowSize), offset - imgRowSize);
 
-      for (var k = 0, kk = map[q].h; k < kk; k++) {
+      for (let k = 0, kk = map[q].h; k < kk; k++) {
         imgData.set(data.subarray(dataOffset, dataOffset + rowSize), offset);
         dataOffset += rowSize;
         offset += imgRowSize;
@@ -172,9 +172,9 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     return iFirstSave + 1;
   });
   addState(InitialState, [_util.OPS.save, _util.OPS.transform, _util.OPS.paintImageMaskXObject, _util.OPS.restore], null, function iterateImageMaskGroup(context, i) {
-    var fnArray = context.fnArray;
-    var iFirstSave = context.iCurr - 3;
-    var pos = (i - iFirstSave) % 4;
+    const fnArray = context.fnArray;
+    const iFirstSave = context.iCurr - 3;
+    const pos = (i - iFirstSave) % 4;
 
     switch (pos) {
       case 0:
@@ -192,26 +192,25 @@ var QueueOptimizer = function QueueOptimizerClosure() {
 
     throw new Error(`iterateImageMaskGroup - invalid pos: ${pos}`);
   }, function foundImageMaskGroup(context, i) {
-    var MIN_IMAGES_IN_MASKS_BLOCK = 10;
-    var MAX_IMAGES_IN_MASKS_BLOCK = 100;
-    var MAX_SAME_IMAGES_IN_MASKS_BLOCK = 1000;
-    var fnArray = context.fnArray,
-        argsArray = context.argsArray;
-    var curr = context.iCurr;
-    var iFirstSave = curr - 3;
-    var iFirstTransform = curr - 2;
-    var iFirstPIMXO = curr - 1;
-    var count = Math.floor((i - iFirstSave) / 4);
+    const MIN_IMAGES_IN_MASKS_BLOCK = 10;
+    const MAX_IMAGES_IN_MASKS_BLOCK = 100;
+    const MAX_SAME_IMAGES_IN_MASKS_BLOCK = 1000;
+    const fnArray = context.fnArray,
+          argsArray = context.argsArray;
+    const curr = context.iCurr;
+    const iFirstSave = curr - 3;
+    const iFirstTransform = curr - 2;
+    const iFirstPIMXO = curr - 1;
+    let count = Math.floor((i - iFirstSave) / 4);
     count = handlePaintSolidColorImageMask(iFirstSave, count, fnArray, argsArray);
 
     if (count < MIN_IMAGES_IN_MASKS_BLOCK) {
       return i - (i - iFirstSave) % 4;
     }
 
-    var q;
-    var isSameImage = false;
-    var iTransform, transformArgs;
-    var firstPIMXOArg0 = argsArray[iFirstPIMXO][0];
+    let isSameImage = false;
+    let iTransform, transformArgs;
+    const firstPIMXOArg0 = argsArray[iFirstPIMXO][0];
     const firstTransformArg0 = argsArray[iFirstTransform][0],
           firstTransformArg1 = argsArray[iFirstTransform][1],
           firstTransformArg2 = argsArray[iFirstTransform][2],
@@ -220,9 +219,9 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     if (firstTransformArg1 === firstTransformArg2) {
       isSameImage = true;
       iTransform = iFirstTransform + 4;
-      var iPIMXO = iFirstPIMXO + 4;
+      let iPIMXO = iFirstPIMXO + 4;
 
-      for (q = 1; q < count; q++, iTransform += 4, iPIMXO += 4) {
+      for (let q = 1; q < count; q++, iTransform += 4, iPIMXO += 4) {
         transformArgs = argsArray[iTransform];
 
         if (argsArray[iPIMXO][0] !== firstPIMXOArg0 || transformArgs[0] !== firstTransformArg0 || transformArgs[1] !== firstTransformArg1 || transformArgs[2] !== firstTransformArg2 || transformArgs[3] !== firstTransformArg3) {
@@ -239,10 +238,10 @@ var QueueOptimizer = function QueueOptimizerClosure() {
 
     if (isSameImage) {
       count = Math.min(count, MAX_SAME_IMAGES_IN_MASKS_BLOCK);
-      var positions = new Float32Array(count * 2);
+      const positions = new Float32Array(count * 2);
       iTransform = iFirstTransform;
 
-      for (q = 0; q < count; q++, iTransform += 4) {
+      for (let q = 0; q < count; q++, iTransform += 4) {
         transformArgs = argsArray[iTransform];
         positions[q << 1] = transformArgs[4];
         positions[(q << 1) + 1] = transformArgs[5];
@@ -252,11 +251,11 @@ var QueueOptimizer = function QueueOptimizerClosure() {
       argsArray.splice(iFirstSave, count * 4, [firstPIMXOArg0, firstTransformArg0, firstTransformArg1, firstTransformArg2, firstTransformArg3, positions]);
     } else {
       count = Math.min(count, MAX_IMAGES_IN_MASKS_BLOCK);
-      var images = [];
+      const images = [];
 
-      for (q = 0; q < count; q++) {
+      for (let q = 0; q < count; q++) {
         transformArgs = argsArray[iFirstTransform + (q << 2)];
-        var maskParams = argsArray[iFirstPIMXO + (q << 2)][0];
+        const maskParams = argsArray[iFirstPIMXO + (q << 2)][0];
         images.push({
           data: maskParams.data,
           width: maskParams.width,
@@ -272,14 +271,14 @@ var QueueOptimizer = function QueueOptimizerClosure() {
     return iFirstSave + 1;
   });
   addState(InitialState, [_util.OPS.save, _util.OPS.transform, _util.OPS.paintImageXObject, _util.OPS.restore], function (context) {
-    var argsArray = context.argsArray;
-    var iFirstTransform = context.iCurr - 2;
+    const argsArray = context.argsArray;
+    const iFirstTransform = context.iCurr - 2;
     return argsArray[iFirstTransform][1] === 0 && argsArray[iFirstTransform][2] === 0;
   }, function iterateImageGroup(context, i) {
-    var fnArray = context.fnArray,
-        argsArray = context.argsArray;
-    var iFirstSave = context.iCurr - 3;
-    var pos = (i - iFirstSave) % 4;
+    const fnArray = context.fnArray,
+          argsArray = context.argsArray;
+    const iFirstSave = context.iCurr - 3;
+    const pos = (i - iFirstSave) % 4;
 
     switch (pos) {
       case 0:
@@ -290,9 +289,9 @@ var QueueOptimizer = function QueueOptimizerClosure() {
           return false;
         }
 
-        var iFirstTransform = context.iCurr - 2;
-        var firstTransformArg0 = argsArray[iFirstTransform][0];
-        var firstTransformArg3 = argsArray[iFirstTransform][3];
+        const iFirstTransform = context.iCurr - 2;
+        const firstTransformArg0 = argsArray[iFirstTransform][0];
+        const firstTransformArg3 = argsArray[iFirstTransform][3];
 
         if (argsArray[i][0] !== firstTransformArg0 || argsArray[i][1] !== 0 || argsArray[i][2] !== 0 || argsArray[i][3] !== firstTransformArg3) {
           return false;
@@ -305,8 +304,8 @@ var QueueOptimizer = function QueueOptimizerClosure() {
           return false;
         }
 
-        var iFirstPIXO = context.iCurr - 1;
-        var firstPIXOArg0 = argsArray[iFirstPIXO][0];
+        const iFirstPIXO = context.iCurr - 1;
+        const firstPIXOArg0 = argsArray[iFirstPIXO][0];
 
         if (argsArray[i][0] !== firstPIXOArg0) {
           return false;
@@ -320,42 +319,42 @@ var QueueOptimizer = function QueueOptimizerClosure() {
 
     throw new Error(`iterateImageGroup - invalid pos: ${pos}`);
   }, function (context, i) {
-    var MIN_IMAGES_IN_BLOCK = 3;
-    var MAX_IMAGES_IN_BLOCK = 1000;
-    var fnArray = context.fnArray,
-        argsArray = context.argsArray;
-    var curr = context.iCurr;
-    var iFirstSave = curr - 3;
-    var iFirstTransform = curr - 2;
-    var iFirstPIXO = curr - 1;
-    var firstPIXOArg0 = argsArray[iFirstPIXO][0];
-    var firstTransformArg0 = argsArray[iFirstTransform][0];
-    var firstTransformArg3 = argsArray[iFirstTransform][3];
-    var count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_BLOCK);
+    const MIN_IMAGES_IN_BLOCK = 3;
+    const MAX_IMAGES_IN_BLOCK = 1000;
+    const fnArray = context.fnArray,
+          argsArray = context.argsArray;
+    const curr = context.iCurr;
+    const iFirstSave = curr - 3;
+    const iFirstTransform = curr - 2;
+    const iFirstPIXO = curr - 1;
+    const firstPIXOArg0 = argsArray[iFirstPIXO][0];
+    const firstTransformArg0 = argsArray[iFirstTransform][0];
+    const firstTransformArg3 = argsArray[iFirstTransform][3];
+    const count = Math.min(Math.floor((i - iFirstSave) / 4), MAX_IMAGES_IN_BLOCK);
 
     if (count < MIN_IMAGES_IN_BLOCK) {
       return i - (i - iFirstSave) % 4;
     }
 
-    var positions = new Float32Array(count * 2);
-    var iTransform = iFirstTransform;
+    const positions = new Float32Array(count * 2);
+    let iTransform = iFirstTransform;
 
-    for (var q = 0; q < count; q++, iTransform += 4) {
-      var transformArgs = argsArray[iTransform];
+    for (let q = 0; q < count; q++, iTransform += 4) {
+      const transformArgs = argsArray[iTransform];
       positions[q << 1] = transformArgs[4];
       positions[(q << 1) + 1] = transformArgs[5];
     }
 
-    var args = [firstPIXOArg0, firstTransformArg0, firstTransformArg3, positions];
+    const args = [firstPIXOArg0, firstTransformArg0, firstTransformArg3, positions];
     fnArray.splice(iFirstSave, count * 4, _util.OPS.paintImageXObjectRepeat);
     argsArray.splice(iFirstSave, count * 4, args);
     return iFirstSave + 1;
   });
   addState(InitialState, [_util.OPS.beginText, _util.OPS.setFont, _util.OPS.setTextMatrix, _util.OPS.showText, _util.OPS.endText], null, function iterateShowTextGroup(context, i) {
-    var fnArray = context.fnArray,
-        argsArray = context.argsArray;
-    var iFirstSave = context.iCurr - 4;
-    var pos = (i - iFirstSave) % 5;
+    const fnArray = context.fnArray,
+          argsArray = context.argsArray;
+    const iFirstSave = context.iCurr - 4;
+    const pos = (i - iFirstSave) % 5;
 
     switch (pos) {
       case 0:
@@ -372,9 +371,9 @@ var QueueOptimizer = function QueueOptimizerClosure() {
           return false;
         }
 
-        var iFirstSetFont = context.iCurr - 3;
-        var firstSetFontArg0 = argsArray[iFirstSetFont][0];
-        var firstSetFontArg1 = argsArray[iFirstSetFont][1];
+        const iFirstSetFont = context.iCurr - 3;
+        const firstSetFontArg0 = argsArray[iFirstSetFont][0];
+        const firstSetFontArg1 = argsArray[iFirstSetFont][1];
 
         if (argsArray[i][0] !== firstSetFontArg0 || argsArray[i][1] !== firstSetFontArg1) {
           return false;
@@ -388,34 +387,34 @@ var QueueOptimizer = function QueueOptimizerClosure() {
 
     throw new Error(`iterateShowTextGroup - invalid pos: ${pos}`);
   }, function (context, i) {
-    var MIN_CHARS_IN_BLOCK = 3;
-    var MAX_CHARS_IN_BLOCK = 1000;
-    var fnArray = context.fnArray,
-        argsArray = context.argsArray;
-    var curr = context.iCurr;
-    var iFirstBeginText = curr - 4;
-    var iFirstSetFont = curr - 3;
-    var iFirstSetTextMatrix = curr - 2;
-    var iFirstShowText = curr - 1;
-    var iFirstEndText = curr;
-    var firstSetFontArg0 = argsArray[iFirstSetFont][0];
-    var firstSetFontArg1 = argsArray[iFirstSetFont][1];
-    var count = Math.min(Math.floor((i - iFirstBeginText) / 5), MAX_CHARS_IN_BLOCK);
+    const MIN_CHARS_IN_BLOCK = 3;
+    const MAX_CHARS_IN_BLOCK = 1000;
+    const fnArray = context.fnArray,
+          argsArray = context.argsArray;
+    const curr = context.iCurr;
+    const iFirstBeginText = curr - 4;
+    const iFirstSetFont = curr - 3;
+    const iFirstSetTextMatrix = curr - 2;
+    const iFirstShowText = curr - 1;
+    const iFirstEndText = curr;
+    const firstSetFontArg0 = argsArray[iFirstSetFont][0];
+    const firstSetFontArg1 = argsArray[iFirstSetFont][1];
+    let count = Math.min(Math.floor((i - iFirstBeginText) / 5), MAX_CHARS_IN_BLOCK);
 
     if (count < MIN_CHARS_IN_BLOCK) {
       return i - (i - iFirstBeginText) % 5;
     }
 
-    var iFirst = iFirstBeginText;
+    let iFirst = iFirstBeginText;
 
     if (iFirstBeginText >= 4 && fnArray[iFirstBeginText - 4] === fnArray[iFirstSetFont] && fnArray[iFirstBeginText - 3] === fnArray[iFirstSetTextMatrix] && fnArray[iFirstBeginText - 2] === fnArray[iFirstShowText] && fnArray[iFirstBeginText - 1] === fnArray[iFirstEndText] && argsArray[iFirstBeginText - 4][0] === firstSetFontArg0 && argsArray[iFirstBeginText - 4][1] === firstSetFontArg1) {
       count++;
       iFirst -= 5;
     }
 
-    var iEndText = iFirst + 4;
+    let iEndText = iFirst + 4;
 
-    for (var q = 1; q < count; q++) {
+    for (let q = 1; q < count; q++) {
       fnArray.splice(iEndText, 3);
       argsArray.splice(iEndText, 3);
       iEndText += 2;
@@ -522,7 +521,7 @@ var QueueOptimizer = function QueueOptimizerClosure() {
   return QueueOptimizer;
 }();
 
-var NullOptimizer = function NullOptimizerClosure() {
+const NullOptimizer = function NullOptimizerClosure() {
   function NullOptimizer(queue) {
     this.queue = queue;
   }
@@ -541,9 +540,9 @@ var NullOptimizer = function NullOptimizerClosure() {
   return NullOptimizer;
 }();
 
-var OperatorList = function OperatorListClosure() {
-  var CHUNK_SIZE = 1000;
-  var CHUNK_SIZE_ABOUT = CHUNK_SIZE - 5;
+const OperatorList = function OperatorListClosure() {
+  const CHUNK_SIZE = 1000;
+  const CHUNK_SIZE_ABOUT = CHUNK_SIZE - 5;
 
   function OperatorList(intent, streamSink) {
     this._streamSink = streamSink;
@@ -613,7 +612,7 @@ var OperatorList = function OperatorListClosure() {
         this.dependencies.add(dependency);
       }
 
-      for (var i = 0, ii = opList.length; i < ii; i++) {
+      for (let i = 0, ii = opList.length; i < ii; i++) {
         this.addOp(opList.fnArray[i], opList.argsArray[i]);
       }
     },

+ 1 - 1
lib/core/parser.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 142 - 149
lib/core/pattern.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ var _primitives = require("./primitives.js");
 
 var _core_utils = require("./core_utils.js");
 
-var ShadingType = {
+const ShadingType = {
   FUNCTION_BASED: 1,
   AXIAL: 2,
   RADIAL: 3,
@@ -45,7 +45,7 @@ var ShadingType = {
   TENSOR_PATCH_MESH: 7
 };
 
-var Pattern = function PatternClosure() {
+const Pattern = function PatternClosure() {
   function Pattern() {
     (0, _util.unreachable)("should not call Pattern constructor");
   }
@@ -57,8 +57,8 @@ var Pattern = function PatternClosure() {
   };
 
   Pattern.parseShading = function (shading, matrix, xref, res, handler, pdfFunctionFactory, localColorSpaceCache) {
-    var dict = (0, _primitives.isStream)(shading) ? shading.dict : shading;
-    var type = dict.get("ShadingType");
+    const dict = (0, _primitives.isStream)(shading) ? shading.dict : shading;
+    const type = dict.get("ShadingType");
 
     try {
       switch (type) {
@@ -92,7 +92,7 @@ var Pattern = function PatternClosure() {
 }();
 
 exports.Pattern = Pattern;
-var Shadings = {};
+const Shadings = {};
 Shadings.SMALL_NUMBER = 1e-6;
 
 Shadings.RadialAxial = function RadialAxialClosure() {
@@ -119,32 +119,27 @@ Shadings.RadialAxial = function RadialAxialClosure() {
       this.bbox = null;
     }
 
-    var t0 = 0.0,
+    let t0 = 0.0,
         t1 = 1.0;
 
     if (dict.has("Domain")) {
-      var domainArr = dict.getArray("Domain");
+      const domainArr = dict.getArray("Domain");
       t0 = domainArr[0];
       t1 = domainArr[1];
     }
 
-    var extendStart = false,
+    let extendStart = false,
         extendEnd = false;
 
     if (dict.has("Extend")) {
-      var extendArr = dict.getArray("Extend");
+      const extendArr = dict.getArray("Extend");
       extendStart = extendArr[0];
       extendEnd = extendArr[1];
     }
 
     if (this.shadingType === ShadingType.RADIAL && (!extendStart || !extendEnd)) {
-      var x1 = this.coordsArr[0];
-      var y1 = this.coordsArr[1];
-      var r1 = this.coordsArr[2];
-      var x2 = this.coordsArr[3];
-      var y2 = this.coordsArr[4];
-      var r2 = this.coordsArr[5];
-      var distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+      const [x1, y1, r1, x2, y2, r2] = this.coordsArr;
+      const distance = Math.hypot(x1 - x2, y1 - y2);
 
       if (r1 <= r2 + distance && r2 <= r1 + distance) {
         (0, _util.warn)("Unsupported radial gradient.");
@@ -153,32 +148,32 @@ Shadings.RadialAxial = function RadialAxialClosure() {
 
     this.extendStart = extendStart;
     this.extendEnd = extendEnd;
-    var fnObj = dict.getRaw("Function");
-    var fn = pdfFunctionFactory.createFromArray(fnObj);
+    const fnObj = dict.getRaw("Function");
+    const fn = pdfFunctionFactory.createFromArray(fnObj);
     const NUMBER_OF_SAMPLES = 10;
     const step = (t1 - t0) / NUMBER_OF_SAMPLES;
-    var colorStops = this.colorStops = [];
+    const colorStops = this.colorStops = [];
 
     if (t0 >= t1 || step <= 0) {
       (0, _util.info)("Bad shading domain.");
       return;
     }
 
-    var color = new Float32Array(cs.numComps),
-        ratio = new Float32Array(1);
-    var rgbColor;
+    const color = new Float32Array(cs.numComps),
+          ratio = new Float32Array(1);
+    let rgbColor;
 
     for (let i = 0; i <= NUMBER_OF_SAMPLES; i++) {
       ratio[0] = t0 + i * step;
       fn(ratio, 0, color, 0);
       rgbColor = cs.getRgb(color, 0);
 
-      var cssColor = _util.Util.makeHexColor(rgbColor[0], rgbColor[1], rgbColor[2]);
+      const cssColor = _util.Util.makeHexColor(rgbColor[0], rgbColor[1], rgbColor[2]);
 
       colorStops.push([i / NUMBER_OF_SAMPLES, cssColor]);
     }
 
-    var background = "transparent";
+    let background = "transparent";
 
     if (dict.has("Background")) {
       rgbColor = cs.getRgb(dict.get("Background"), 0);
@@ -200,9 +195,9 @@ Shadings.RadialAxial = function RadialAxialClosure() {
 
   RadialAxial.prototype = {
     getIR: function RadialAxial_getIR() {
-      var coordsArr = this.coordsArr;
-      var shadingType = this.shadingType;
-      var type, p0, p1, r0, r1;
+      const coordsArr = this.coordsArr;
+      const shadingType = this.shadingType;
+      let type, p0, p1, r0, r1;
 
       if (shadingType === ShadingType.AXIAL) {
         p0 = [coordsArr[0], coordsArr[1]];
@@ -220,14 +215,14 @@ Shadings.RadialAxial = function RadialAxialClosure() {
         (0, _util.unreachable)(`getPattern type unknown: ${shadingType}`);
       }
 
-      var matrix = this.matrix;
+      const matrix = this.matrix;
 
       if (matrix) {
         p0 = _util.Util.applyTransform(p0, matrix);
         p1 = _util.Util.applyTransform(p1, matrix);
 
         if (shadingType === ShadingType.RADIAL) {
-          var scale = _util.Util.singularValueDecompose2dScale(matrix);
+          const scale = _util.Util.singularValueDecompose2dScale(matrix);
 
           r0 *= scale[0];
           r1 *= scale[1];
@@ -246,9 +241,9 @@ Shadings.Mesh = function MeshClosure() {
     this.context = context;
     this.buffer = 0;
     this.bufferLength = 0;
-    var numComps = context.numComps;
+    const numComps = context.numComps;
     this.tmpCompsBuf = new Float32Array(numComps);
-    var csNumComps = context.colorSpace.numComps;
+    const csNumComps = context.colorSpace.numComps;
     this.tmpCsCompsBuf = context.colorFn ? new Float32Array(csNumComps) : this.tmpCompsBuf;
   }
 
@@ -262,7 +257,7 @@ Shadings.Mesh = function MeshClosure() {
         return true;
       }
 
-      var nextByte = this.stream.getByte();
+      const nextByte = this.stream.getByte();
 
       if (nextByte < 0) {
         return false;
@@ -274,8 +269,8 @@ Shadings.Mesh = function MeshClosure() {
     },
 
     readBits: function MeshStreamReader_readBits(n) {
-      var buffer = this.buffer;
-      var bufferLength = this.bufferLength;
+      let buffer = this.buffer;
+      let bufferLength = this.bufferLength;
 
       if (n === 32) {
         if (bufferLength === 0) {
@@ -283,7 +278,7 @@ Shadings.Mesh = function MeshClosure() {
         }
 
         buffer = buffer << 24 | this.stream.getByte() << 16 | this.stream.getByte() << 8 | this.stream.getByte();
-        var nextByte = this.stream.getByte();
+        const nextByte = this.stream.getByte();
         this.buffer = nextByte & (1 << bufferLength) - 1;
         return (buffer << 8 - bufferLength | (nextByte & 0xff) >> bufferLength) >>> 0;
       }
@@ -310,26 +305,26 @@ Shadings.Mesh = function MeshClosure() {
       return this.readBits(this.context.bitsPerFlag);
     },
     readCoordinate: function MeshStreamReader_readCoordinate() {
-      var bitsPerCoordinate = this.context.bitsPerCoordinate;
-      var xi = this.readBits(bitsPerCoordinate);
-      var yi = this.readBits(bitsPerCoordinate);
-      var decode = this.context.decode;
-      var scale = bitsPerCoordinate < 32 ? 1 / ((1 << bitsPerCoordinate) - 1) : 2.3283064365386963e-10;
+      const bitsPerCoordinate = this.context.bitsPerCoordinate;
+      const xi = this.readBits(bitsPerCoordinate);
+      const yi = this.readBits(bitsPerCoordinate);
+      const decode = this.context.decode;
+      const scale = bitsPerCoordinate < 32 ? 1 / ((1 << bitsPerCoordinate) - 1) : 2.3283064365386963e-10;
       return [xi * scale * (decode[1] - decode[0]) + decode[0], yi * scale * (decode[3] - decode[2]) + decode[2]];
     },
     readComponents: function MeshStreamReader_readComponents() {
-      var numComps = this.context.numComps;
-      var bitsPerComponent = this.context.bitsPerComponent;
-      var scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) : 2.3283064365386963e-10;
-      var decode = this.context.decode;
-      var components = this.tmpCompsBuf;
-
-      for (var i = 0, j = 4; i < numComps; i++, j += 2) {
-        var ci = this.readBits(bitsPerComponent);
+      const numComps = this.context.numComps;
+      const bitsPerComponent = this.context.bitsPerComponent;
+      const scale = bitsPerComponent < 32 ? 1 / ((1 << bitsPerComponent) - 1) : 2.3283064365386963e-10;
+      const decode = this.context.decode;
+      const components = this.tmpCompsBuf;
+
+      for (let i = 0, j = 4; i < numComps; i++, j += 2) {
+        const ci = this.readBits(bitsPerComponent);
         components[i] = ci * scale * (decode[j + 1] - decode[j]) + decode[j];
       }
 
-      var color = this.tmpCsCompsBuf;
+      const color = this.tmpCsCompsBuf;
 
       if (this.context.colorFn) {
         this.context.colorFn(components, 0, color, 0);
@@ -340,16 +335,16 @@ Shadings.Mesh = function MeshClosure() {
   };
 
   function decodeType4Shading(mesh, reader) {
-    var coords = mesh.coords;
-    var colors = mesh.colors;
-    var operators = [];
-    var ps = [];
-    var verticesLeft = 0;
+    const coords = mesh.coords;
+    const colors = mesh.colors;
+    const operators = [];
+    const ps = [];
+    let verticesLeft = 0;
 
     while (reader.hasData) {
-      var f = reader.readFlag();
-      var coord = reader.readCoordinate();
-      var color = reader.readComponents();
+      const f = reader.readFlag();
+      const coord = reader.readCoordinate();
+      const color = reader.readComponents();
 
       if (verticesLeft === 0) {
         if (!(0 <= f && f <= 2)) {
@@ -390,13 +385,13 @@ Shadings.Mesh = function MeshClosure() {
   }
 
   function decodeType5Shading(mesh, reader, verticesPerRow) {
-    var coords = mesh.coords;
-    var colors = mesh.colors;
-    var ps = [];
+    const coords = mesh.coords;
+    const colors = mesh.colors;
+    const ps = [];
 
     while (reader.hasData) {
-      var coord = reader.readCoordinate();
-      var color = reader.readComponents();
+      const coord = reader.readCoordinate();
+      const color = reader.readComponents();
       ps.push(coords.length);
       coords.push(coord);
       colors.push(color);
@@ -410,24 +405,24 @@ Shadings.Mesh = function MeshClosure() {
     });
   }
 
-  var MIN_SPLIT_PATCH_CHUNKS_AMOUNT = 3;
-  var MAX_SPLIT_PATCH_CHUNKS_AMOUNT = 20;
-  var TRIANGLE_DENSITY = 20;
+  const MIN_SPLIT_PATCH_CHUNKS_AMOUNT = 3;
+  const MAX_SPLIT_PATCH_CHUNKS_AMOUNT = 20;
+  const TRIANGLE_DENSITY = 20;
 
-  var getB = function getBClosure() {
+  const getB = function getBClosure() {
     function buildB(count) {
-      var lut = [];
+      const lut = [];
 
-      for (var i = 0; i <= count; i++) {
-        var t = i / count,
-            t_ = 1 - t;
+      for (let i = 0; i <= count; i++) {
+        const t = i / count,
+              t_ = 1 - t;
         lut.push(new Float32Array([t_ * t_ * t_, 3 * t * t_ * t_, 3 * t * t * t_, t * t * t]));
       }
 
       return lut;
     }
 
-    var cache = [];
+    const cache = [];
     return function getB(count) {
       if (!cache[count]) {
         cache[count] = buildB(count);
@@ -438,34 +433,34 @@ Shadings.Mesh = function MeshClosure() {
   }();
 
   function buildFigureFromPatch(mesh, index) {
-    var figure = mesh.figures[index];
+    const figure = mesh.figures[index];
     (0, _util.assert)(figure.type === "patch", "Unexpected patch mesh figure");
-    var coords = mesh.coords,
-        colors = mesh.colors;
-    var pi = figure.coords;
-    var ci = figure.colors;
-    var figureMinX = Math.min(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);
-    var figureMinY = Math.min(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);
-    var figureMaxX = Math.max(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);
-    var figureMaxY = Math.max(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);
-    var splitXBy = Math.ceil((figureMaxX - figureMinX) * TRIANGLE_DENSITY / (mesh.bounds[2] - mesh.bounds[0]));
+    const coords = mesh.coords,
+          colors = mesh.colors;
+    const pi = figure.coords;
+    const ci = figure.colors;
+    const figureMinX = Math.min(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);
+    const figureMinY = Math.min(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);
+    const figureMaxX = Math.max(coords[pi[0]][0], coords[pi[3]][0], coords[pi[12]][0], coords[pi[15]][0]);
+    const figureMaxY = Math.max(coords[pi[0]][1], coords[pi[3]][1], coords[pi[12]][1], coords[pi[15]][1]);
+    let splitXBy = Math.ceil((figureMaxX - figureMinX) * TRIANGLE_DENSITY / (mesh.bounds[2] - mesh.bounds[0]));
     splitXBy = Math.max(MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitXBy));
-    var splitYBy = Math.ceil((figureMaxY - figureMinY) * TRIANGLE_DENSITY / (mesh.bounds[3] - mesh.bounds[1]));
+    let splitYBy = Math.ceil((figureMaxY - figureMinY) * TRIANGLE_DENSITY / (mesh.bounds[3] - mesh.bounds[1]));
     splitYBy = Math.max(MIN_SPLIT_PATCH_CHUNKS_AMOUNT, Math.min(MAX_SPLIT_PATCH_CHUNKS_AMOUNT, splitYBy));
-    var verticesPerRow = splitXBy + 1;
-    var figureCoords = new Int32Array((splitYBy + 1) * verticesPerRow);
-    var figureColors = new Int32Array((splitYBy + 1) * verticesPerRow);
-    var k = 0;
-    var cl = new Uint8Array(3),
-        cr = new Uint8Array(3);
-    var c0 = colors[ci[0]],
-        c1 = colors[ci[1]],
-        c2 = colors[ci[2]],
-        c3 = colors[ci[3]];
-    var bRow = getB(splitYBy),
-        bCol = getB(splitXBy);
-
-    for (var row = 0; row <= splitYBy; row++) {
+    const verticesPerRow = splitXBy + 1;
+    const figureCoords = new Int32Array((splitYBy + 1) * verticesPerRow);
+    const figureColors = new Int32Array((splitYBy + 1) * verticesPerRow);
+    let k = 0;
+    const cl = new Uint8Array(3),
+          cr = new Uint8Array(3);
+    const c0 = colors[ci[0]],
+          c1 = colors[ci[1]],
+          c2 = colors[ci[2]],
+          c3 = colors[ci[3]];
+    const bRow = getB(splitYBy),
+          bCol = getB(splitXBy);
+
+    for (let row = 0; row <= splitYBy; row++) {
       cl[0] = (c0[0] * (splitYBy - row) + c2[0] * row) / splitYBy | 0;
       cl[1] = (c0[1] * (splitYBy - row) + c2[1] * row) / splitYBy | 0;
       cl[2] = (c0[2] * (splitYBy - row) + c2[2] * row) / splitYBy | 0;
@@ -473,18 +468,18 @@ Shadings.Mesh = function MeshClosure() {
       cr[1] = (c1[1] * (splitYBy - row) + c3[1] * row) / splitYBy | 0;
       cr[2] = (c1[2] * (splitYBy - row) + c3[2] * row) / splitYBy | 0;
 
-      for (var col = 0; col <= splitXBy; col++, k++) {
+      for (let col = 0; col <= splitXBy; col++, k++) {
         if ((row === 0 || row === splitYBy) && (col === 0 || col === splitXBy)) {
           continue;
         }
 
-        var x = 0,
+        let x = 0,
             y = 0;
-        var q = 0;
+        let q = 0;
 
-        for (var i = 0; i <= 3; i++) {
-          for (var j = 0; j <= 3; j++, q++) {
-            var m = bRow[row][i] * bCol[col][j];
+        for (let i = 0; i <= 3; i++) {
+          for (let j = 0; j <= 3; j++, q++) {
+            const m = bRow[row][i] * bCol[col][j];
             x += coords[pi[q]][0] * m;
             y += coords[pi[q]][1] * m;
           }
@@ -493,7 +488,7 @@ Shadings.Mesh = function MeshClosure() {
         figureCoords[k] = coords.length;
         coords.push([x, y]);
         figureColors[k] = colors.length;
-        var newColor = new Uint8Array(3);
+        const newColor = new Uint8Array(3);
         newColor[0] = (cl[0] * (splitXBy - col) + cr[0] * col) / splitXBy | 0;
         newColor[1] = (cl[1] * (splitXBy - col) + cr[1] * col) / splitXBy | 0;
         newColor[2] = (cl[2] * (splitXBy - col) + cr[2] * col) / splitXBy | 0;
@@ -518,32 +513,31 @@ Shadings.Mesh = function MeshClosure() {
   }
 
   function decodeType6Shading(mesh, reader) {
-    var coords = mesh.coords;
-    var colors = mesh.colors;
-    var ps = new Int32Array(16);
-    var cs = new Int32Array(4);
+    const coords = mesh.coords;
+    const colors = mesh.colors;
+    const ps = new Int32Array(16);
+    const cs = new Int32Array(4);
 
     while (reader.hasData) {
-      var f = reader.readFlag();
+      const f = reader.readFlag();
 
       if (!(0 <= f && f <= 3)) {
         throw new _util.FormatError("Unknown type6 flag");
       }
 
-      var i, ii;
-      var pi = coords.length;
+      const pi = coords.length;
 
-      for (i = 0, ii = f !== 0 ? 8 : 12; i < ii; i++) {
+      for (let i = 0, ii = f !== 0 ? 8 : 12; i < ii; i++) {
         coords.push(reader.readCoordinate());
       }
 
-      var ci = colors.length;
+      const ci = colors.length;
 
-      for (i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
+      for (let i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
         colors.push(reader.readComponents());
       }
 
-      var tmp1, tmp2, tmp3, tmp4;
+      let tmp1, tmp2, tmp3, tmp4;
 
       switch (f) {
         case 0:
@@ -649,32 +643,31 @@ Shadings.Mesh = function MeshClosure() {
   }
 
   function decodeType7Shading(mesh, reader) {
-    var coords = mesh.coords;
-    var colors = mesh.colors;
-    var ps = new Int32Array(16);
-    var cs = new Int32Array(4);
+    const coords = mesh.coords;
+    const colors = mesh.colors;
+    const ps = new Int32Array(16);
+    const cs = new Int32Array(4);
 
     while (reader.hasData) {
-      var f = reader.readFlag();
+      const f = reader.readFlag();
 
       if (!(0 <= f && f <= 3)) {
         throw new _util.FormatError("Unknown type7 flag");
       }
 
-      var i, ii;
-      var pi = coords.length;
+      const pi = coords.length;
 
-      for (i = 0, ii = f !== 0 ? 12 : 16; i < ii; i++) {
+      for (let i = 0, ii = f !== 0 ? 12 : 16; i < ii; i++) {
         coords.push(reader.readCoordinate());
       }
 
-      var ci = colors.length;
+      const ci = colors.length;
 
-      for (i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
+      for (let i = 0, ii = f !== 0 ? 2 : 4; i < ii; i++) {
         colors.push(reader.readComponents());
       }
 
-      var tmp1, tmp2, tmp3, tmp4;
+      let tmp1, tmp2, tmp3, tmp4;
 
       switch (f) {
         case 0:
@@ -788,14 +781,14 @@ Shadings.Mesh = function MeshClosure() {
   }
 
   function updateBounds(mesh) {
-    var minX = mesh.coords[0][0],
+    let minX = mesh.coords[0][0],
         minY = mesh.coords[0][1],
         maxX = minX,
         maxY = minY;
 
-    for (var i = 1, ii = mesh.coords.length; i < ii; i++) {
-      var x = mesh.coords[i][0],
-          y = mesh.coords[i][1];
+    for (let i = 1, ii = mesh.coords.length; i < ii; i++) {
+      const x = mesh.coords[i][0],
+            y = mesh.coords[i][1];
       minX = minX > x ? x : minX;
       minY = minY > y ? y : minY;
       maxX = maxX < x ? x : maxX;
@@ -806,34 +799,34 @@ Shadings.Mesh = function MeshClosure() {
   }
 
   function packData(mesh) {
-    var i, ii, j, jj;
-    var coords = mesh.coords;
-    var coordsPacked = new Float32Array(coords.length * 2);
+    let i, ii, j, jj;
+    const coords = mesh.coords;
+    const coordsPacked = new Float32Array(coords.length * 2);
 
     for (i = 0, j = 0, ii = coords.length; i < ii; i++) {
-      var xy = coords[i];
+      const xy = coords[i];
       coordsPacked[j++] = xy[0];
       coordsPacked[j++] = xy[1];
     }
 
     mesh.coords = coordsPacked;
-    var colors = mesh.colors;
-    var colorsPacked = new Uint8Array(colors.length * 3);
+    const colors = mesh.colors;
+    const colorsPacked = new Uint8Array(colors.length * 3);
 
     for (i = 0, j = 0, ii = colors.length; i < ii; i++) {
-      var c = colors[i];
+      const c = colors[i];
       colorsPacked[j++] = c[0];
       colorsPacked[j++] = c[1];
       colorsPacked[j++] = c[2];
     }
 
     mesh.colors = colorsPacked;
-    var figures = mesh.figures;
+    const figures = mesh.figures;
 
     for (i = 0, ii = figures.length; i < ii; i++) {
-      var figure = figures[i],
-          ps = figure.coords,
-          cs = figure.colors;
+      const figure = figures[i],
+            ps = figure.coords,
+            cs = figure.colors;
 
       for (j = 0, jj = ps.length; j < jj; j++) {
         ps[j] *= 2;
@@ -847,7 +840,7 @@ Shadings.Mesh = function MeshClosure() {
       throw new _util.FormatError("Mesh data is not a stream");
     }
 
-    var dict = stream.dict;
+    const dict = stream.dict;
     this.matrix = matrix;
     this.shadingType = dict.get("ShadingType");
     this.type = "Pattern";
@@ -869,12 +862,12 @@ Shadings.Mesh = function MeshClosure() {
 
     this.cs = cs;
     this.background = dict.has("Background") ? cs.getRgb(dict.get("Background"), 0) : null;
-    var fnObj = dict.getRaw("Function");
-    var fn = fnObj ? pdfFunctionFactory.createFromArray(fnObj) : null;
+    const fnObj = dict.getRaw("Function");
+    const fn = fnObj ? pdfFunctionFactory.createFromArray(fnObj) : null;
     this.coords = [];
     this.colors = [];
     this.figures = [];
-    var decodeContext = {
+    const decodeContext = {
       bitsPerCoordinate: dict.get("BitsPerCoordinate"),
       bitsPerComponent: dict.get("BitsPerComponent"),
       bitsPerFlag: dict.get("BitsPerFlag"),
@@ -883,8 +876,8 @@ Shadings.Mesh = function MeshClosure() {
       colorSpace: cs,
       numComps: fn ? 1 : cs.numComps
     };
-    var reader = new MeshStreamReader(stream, decodeContext);
-    var patchMesh = false;
+    const reader = new MeshStreamReader(stream, decodeContext);
+    let patchMesh = false;
 
     switch (this.shadingType) {
       case ShadingType.FREE_FORM_MESH:
@@ -892,7 +885,7 @@ Shadings.Mesh = function MeshClosure() {
         break;
 
       case ShadingType.LATTICE_FORM_MESH:
-        var verticesPerRow = dict.get("VerticesPerRow") | 0;
+        const verticesPerRow = dict.get("VerticesPerRow") | 0;
 
         if (verticesPerRow < 2) {
           throw new _util.FormatError("Invalid VerticesPerRow");
@@ -919,7 +912,7 @@ Shadings.Mesh = function MeshClosure() {
     if (patchMesh) {
       updateBounds(this);
 
-      for (var i = 0, ii = this.figures.length; i < ii; i++) {
+      for (let i = 0, ii = this.figures.length; i < ii; i++) {
         buildFigureFromPatch(this, i);
       }
     }

+ 22 - 18
lib/core/pdf_manager.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,6 +36,20 @@ var _document = require("./document.js");
 
 var _stream = require("./stream.js");
 
+function parseDocBaseUrl(url) {
+  if (url) {
+    const absoluteUrl = (0, _util.createValidAbsoluteUrl)(url);
+
+    if (absoluteUrl) {
+      return absoluteUrl.href;
+    }
+
+    (0, _util.warn)(`Invalid absolute docBaseUrl: "${url}".`);
+  }
+
+  return null;
+}
+
 class BasePdfManager {
   constructor() {
     if (this.constructor === BasePdfManager) {
@@ -52,19 +66,7 @@ class BasePdfManager {
   }
 
   get docBaseUrl() {
-    let docBaseUrl = null;
-
-    if (this._docBaseUrl) {
-      const absoluteUrl = (0, _util.createValidAbsoluteUrl)(this._docBaseUrl);
-
-      if (absoluteUrl) {
-        docBaseUrl = absoluteUrl.href;
-      } else {
-        (0, _util.warn)(`Invalid absolute docBaseUrl: "${this._docBaseUrl}".`);
-      }
-    }
-
-    return (0, _util.shadow)(this, "docBaseUrl", docBaseUrl);
+    return this._docBaseUrl;
   }
 
   onLoadedStream() {
@@ -122,12 +124,13 @@ class BasePdfManager {
 }
 
 class LocalPdfManager extends BasePdfManager {
-  constructor(docId, data, password, evaluatorOptions, docBaseUrl) {
+  constructor(docId, data, password, evaluatorOptions, enableXfa, docBaseUrl) {
     super();
     this._docId = docId;
     this._password = password;
-    this._docBaseUrl = docBaseUrl;
+    this._docBaseUrl = parseDocBaseUrl(docBaseUrl);
     this.evaluatorOptions = evaluatorOptions;
+    this.enableXfa = enableXfa;
     const stream = new _stream.Stream(data);
     this.pdfDocument = new _document.PDFDocument(this, stream);
     this._loadedStreamPromise = Promise.resolve(stream);
@@ -160,13 +163,14 @@ class LocalPdfManager extends BasePdfManager {
 exports.LocalPdfManager = LocalPdfManager;
 
 class NetworkPdfManager extends BasePdfManager {
-  constructor(docId, pdfNetworkStream, args, evaluatorOptions, docBaseUrl) {
+  constructor(docId, pdfNetworkStream, args, evaluatorOptions, enableXfa, docBaseUrl) {
     super();
     this._docId = docId;
     this._password = args.password;
-    this._docBaseUrl = docBaseUrl;
+    this._docBaseUrl = parseDocBaseUrl(docBaseUrl);
     this.msgHandler = args.msgHandler;
     this.evaluatorOptions = evaluatorOptions;
+    this.enableXfa = enableXfa;
     this.streamManager = new _chunked_stream.ChunkedStreamManager(pdfNetworkStream, {
       msgHandler: args.msgHandler,
       length: args.length,

+ 10 - 10
lib/core/primitives.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,10 +36,10 @@ exports.RefSetCache = exports.RefSet = exports.Ref = exports.Name = exports.EOF
 
 var _util = require("../shared/util.js");
 
-var EOF = {};
+const EOF = {};
 exports.EOF = EOF;
 
-var Name = function NameClosure() {
+const Name = function NameClosure() {
   let nameCache = Object.create(null);
 
   function Name(name) {
@@ -49,7 +49,7 @@ var Name = function NameClosure() {
   Name.prototype = {};
 
   Name.get = function Name_get(name) {
-    var nameValue = nameCache[name];
+    const nameValue = nameCache[name];
     return nameValue ? nameValue : nameCache[name] = new Name(name);
   };
 
@@ -62,7 +62,7 @@ var Name = function NameClosure() {
 
 exports.Name = Name;
 
-var Cmd = function CmdClosure() {
+const Cmd = function CmdClosure() {
   let cmdCache = Object.create(null);
 
   function Cmd(cmd) {
@@ -72,7 +72,7 @@ var Cmd = function CmdClosure() {
   Cmd.prototype = {};
 
   Cmd.get = function Cmd_get(cmd) {
-    var cmdValue = cmdCache[cmd];
+    const cmdValue = cmdCache[cmd];
     return cmdValue ? cmdValue : cmdCache[cmd] = new Cmd(cmd);
   };
 
@@ -85,8 +85,8 @@ var Cmd = function CmdClosure() {
 
 exports.Cmd = Cmd;
 
-var Dict = function DictClosure() {
-  var nonSerializable = function nonSerializableClosure() {
+const Dict = function DictClosure() {
+  const nonSerializable = function nonSerializableClosure() {
     return nonSerializable;
   };
 
@@ -179,7 +179,7 @@ var Dict = function DictClosure() {
       return this._map[key] !== undefined;
     },
     forEach: function Dict_forEach(callback) {
-      for (var key in this._map) {
+      for (const key in this._map) {
         callback(key, this.get(key));
       }
     }
@@ -271,7 +271,7 @@ var Dict = function DictClosure() {
 
 exports.Dict = Dict;
 
-var Ref = function RefClosure() {
+const Ref = function RefClosure() {
   let refCache = Object.create(null);
 
   function Ref(num, gen) {

+ 1 - 1
lib/core/ps_parser.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 1 - 1
lib/core/standard_fonts.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 10 - 4
lib/core/stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -284,10 +284,16 @@ var DecodeStream = function DecodeStreamClosure() {
     },
 
     makeSubStream: function DecodeStream_makeSubStream(start, length, dict) {
-      var end = start + length;
+      if (length === undefined) {
+        while (!this.eof) {
+          this.readBlock();
+        }
+      } else {
+        var end = start + length;
 
-      while (this.bufferLength <= end && !this.eof) {
-        this.readBlock();
+        while (this.bufferLength <= end && !this.eof) {
+          this.readBlock();
+        }
       }
 
       return new Stream(this.buffer, start, length, dict);

+ 119 - 108
lib/core/type1_parser.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,10 +34,10 @@ var _stream = require("./stream.js");
 
 var _util = require("../shared/util.js");
 
-var HINTING_ENABLED = false;
+const HINTING_ENABLED = false;
 
-var Type1CharString = function Type1CharStringClosure() {
-  var COMMAND_MAP = {
+const Type1CharString = function Type1CharStringClosure() {
+  const COMMAND_MAP = {
     hstem: [1],
     vstem: [3],
     vmoveto: [4],
@@ -55,22 +55,22 @@ var Type1CharString = function Type1CharStringClosure() {
     hvcurveto: [31]
   };
 
-  function Type1CharString() {
-    this.width = 0;
-    this.lsb = 0;
-    this.flexing = false;
-    this.output = [];
-    this.stack = [];
-  }
+  class Type1CharString {
+    constructor() {
+      this.width = 0;
+      this.lsb = 0;
+      this.flexing = false;
+      this.output = [];
+      this.stack = [];
+    }
 
-  Type1CharString.prototype = {
-    convert: function Type1CharString_convert(encoded, subrs, seacAnalysisEnabled) {
-      var count = encoded.length;
-      var error = false;
-      var wx, sbx, subrNumber;
+    convert(encoded, subrs, seacAnalysisEnabled) {
+      const count = encoded.length;
+      let error = false;
+      let wx, sbx, subrNumber;
 
-      for (var i = 0; i < count; i++) {
-        var value = encoded[i];
+      for (let i = 0; i < count; i++) {
+        let value = encoded[i];
 
         if (value < 32) {
           if (value === 12) {
@@ -103,7 +103,7 @@ var Type1CharString = function Type1CharStringClosure() {
                   break;
                 }
 
-                var dy = this.stack.pop();
+                const dy = this.stack.pop();
                 this.stack.push(0, dy);
                 break;
               }
@@ -235,7 +235,7 @@ var Type1CharString = function Type1CharStringClosure() {
 
               this.stack.pop();
               wx = this.stack.pop();
-              var sby = this.stack.pop();
+              const sby = this.stack.pop();
               sbx = this.stack.pop();
               this.lsb = sbx;
               this.width = wx;
@@ -249,8 +249,8 @@ var Type1CharString = function Type1CharStringClosure() {
                 break;
               }
 
-              var num2 = this.stack.pop();
-              var num1 = this.stack.pop();
+              const num2 = this.stack.pop();
+              const num1 = this.stack.pop();
               this.stack.push(num1 / num2);
               break;
 
@@ -261,10 +261,10 @@ var Type1CharString = function Type1CharStringClosure() {
               }
 
               subrNumber = this.stack.pop();
-              var numArgs = this.stack.pop();
+              const numArgs = this.stack.pop();
 
               if (subrNumber === 0 && numArgs === 3) {
-                var flexArgs = this.stack.splice(this.stack.length - 17, 17);
+                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;
@@ -306,19 +306,19 @@ var Type1CharString = function Type1CharStringClosure() {
       }
 
       return error;
-    },
+    }
 
     executeCommand(howManyArgs, command, keepStack) {
-      var stackLength = this.stack.length;
+      const stackLength = this.stack.length;
 
       if (howManyArgs > stackLength) {
         return true;
       }
 
-      var start = stackLength - howManyArgs;
+      const start = stackLength - howManyArgs;
 
-      for (var i = start; i < stackLength; i++) {
-        var value = this.stack[i];
+      for (let i = start; i < stackLength; i++) {
+        let value = this.stack[i];
 
         if (Number.isInteger(value)) {
           this.output.push(28, value >> 8 & 0xff, value & 0xff);
@@ -339,13 +339,14 @@ var Type1CharString = function Type1CharStringClosure() {
       return false;
     }
 
-  };
+  }
+
   return Type1CharString;
 }();
 
-var Type1Parser = function Type1ParserClosure() {
-  var EEXEC_ENCRYPT_KEY = 55665;
-  var CHAR_STRS_ENCRYPT_KEY = 4330;
+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;
@@ -356,9 +357,9 @@ var Type1Parser = function Type1ParserClosure() {
       return new Uint8Array(0);
     }
 
-    var r = key | 0,
-        c1 = 52845,
-        c2 = 22719,
+    const c1 = 52845,
+          c2 = 22719;
+    let r = key | 0,
         i,
         j;
 
@@ -366,11 +367,11 @@ var Type1Parser = function Type1ParserClosure() {
       r = (data[i] + r) * c1 + c2 & (1 << 16) - 1;
     }
 
-    var count = data.length - discardNumber;
-    var decrypted = new Uint8Array(count);
+    const count = data.length - discardNumber;
+    const decrypted = new Uint8Array(count);
 
     for (i = discardNumber, j = 0; j < count; i++, j++) {
-      var value = data[i];
+      const value = data[i];
       decrypted[j] = value ^ r >> 8;
       r = (value + r) * c1 + c2 & (1 << 16) - 1;
     }
@@ -379,30 +380,30 @@ var Type1Parser = function Type1ParserClosure() {
   }
 
   function decryptAscii(data, key, discardNumber) {
-    var r = key | 0,
-        c1 = 52845,
-        c2 = 22719;
-    var count = data.length,
-        maybeLength = count >>> 1;
-    var decrypted = new Uint8Array(maybeLength);
-    var i, j;
+    const c1 = 52845,
+          c2 = 22719;
+    let r = key | 0;
+    const count = data.length,
+          maybeLength = count >>> 1;
+    const decrypted = new Uint8Array(maybeLength);
+    let i, j;
 
     for (i = 0, j = 0; i < count; i++) {
-      var digit1 = data[i];
+      const digit1 = data[i];
 
       if (!isHexDigit(digit1)) {
         continue;
       }
 
       i++;
-      var digit2;
+      let digit2;
 
       while (i < count && !isHexDigit(digit2 = data[i])) {
         i++;
       }
 
       if (i < count) {
-        var value = parseInt(String.fromCharCode(digit1, digit2), 16);
+        const value = parseInt(String.fromCharCode(digit1, digit2), 16);
         decrypted[j++] = value ^ r >> 8;
         r = (value + r) * c1 + c2 & (1 << 16) - 1;
       }
@@ -415,25 +416,25 @@ var Type1Parser = function Type1ParserClosure() {
     return c === 0x2f || c === 0x5b || c === 0x5d || c === 0x7b || c === 0x7d || c === 0x28 || c === 0x29;
   }
 
-  function Type1Parser(stream, encrypted, seacAnalysisEnabled) {
-    if (encrypted) {
-      var data = stream.getBytes();
-      var 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));
-    }
+  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));
+      }
 
-    this.seacAnalysisEnabled = !!seacAnalysisEnabled;
-    this.stream = stream;
-    this.nextChar();
-  }
+      this.seacAnalysisEnabled = !!seacAnalysisEnabled;
+      this.stream = stream;
+      this.nextChar();
+    }
 
-  Type1Parser.prototype = {
-    readNumberArray: function Type1Parser_readNumberArray() {
+    readNumberArray() {
       this.getToken();
-      var array = [];
+      const array = [];
 
       while (true) {
-        var token = this.getToken();
+        const token = this.getToken();
 
         if (token === null || token === "]" || token === "}") {
           break;
@@ -443,25 +444,30 @@ var Type1Parser = function Type1ParserClosure() {
       }
 
       return array;
-    },
-    readNumber: function Type1Parser_readNumber() {
-      var token = this.getToken();
+    }
+
+    readNumber() {
+      const token = this.getToken();
       return parseFloat(token || 0);
-    },
-    readInt: function Type1Parser_readInt() {
-      var token = this.getToken();
+    }
+
+    readInt() {
+      const token = this.getToken();
       return parseInt(token || 0, 10) | 0;
-    },
-    readBoolean: function Type1Parser_readBoolean() {
-      var token = this.getToken();
+    }
+
+    readBoolean() {
+      const token = this.getToken();
       return token === "true" ? 1 : 0;
-    },
-    nextChar: function Type1_nextChar() {
+    }
+
+    nextChar() {
       return this.currentChar = this.stream.getByte();
-    },
-    getToken: function Type1Parser_getToken() {
-      var comment = false;
-      var ch = this.currentChar;
+    }
+
+    getToken() {
+      let comment = false;
+      let ch = this.currentChar;
 
       while (true) {
         if (ch === -1) {
@@ -486,7 +492,7 @@ var Type1Parser = function Type1ParserClosure() {
         return String.fromCharCode(ch);
       }
 
-      var token = "";
+      let token = "";
 
       do {
         token += String.fromCharCode(ch);
@@ -494,28 +500,30 @@ var Type1Parser = function Type1ParserClosure() {
       } while (ch >= 0 && !(0, _core_utils.isWhiteSpace)(ch) && !isSpecial(ch));
 
       return token;
-    },
-    readCharStrings: function Type1Parser_readCharStrings(bytes, lenIV) {
+    }
+
+    readCharStrings(bytes, lenIV) {
       if (lenIV === -1) {
         return bytes;
       }
 
       return decrypt(bytes, CHAR_STRS_ENCRYPT_KEY, lenIV);
-    },
-    extractFontProgram: function Type1Parser_extractFontProgram(properties) {
-      var stream = this.stream;
-      var subrs = [],
-          charstrings = [];
-      var privateData = Object.create(null);
+    }
+
+    extractFontProgram(properties) {
+      const stream = this.stream;
+      const subrs = [],
+            charstrings = [];
+      const privateData = Object.create(null);
       privateData.lenIV = 4;
-      var program = {
+      const program = {
         subrs: [],
         charstrings: [],
         properties: {
           privateData
         }
       };
-      var token, length, data, lenIV, encoded;
+      let token, length, data, lenIV, encoded;
 
       while ((token = this.getToken()) !== null) {
         if (token !== "/") {
@@ -542,7 +550,7 @@ var Type1Parser = function Type1ParserClosure() {
                 continue;
               }
 
-              var glyph = this.getToken();
+              const glyph = this.getToken();
               length = this.readInt();
               this.getToken();
               data = length > 0 ? stream.getBytes(length) : new Uint8Array(0);
@@ -590,7 +598,7 @@ var Type1Parser = function Type1ParserClosure() {
           case "OtherBlues":
           case "FamilyBlues":
           case "FamilyOtherBlues":
-            var blueArray = this.readNumberArray();
+            const blueArray = this.readNumberArray();
 
             if (blueArray.length > 0 && blueArray.length % 2 === 0 && HINTING_ENABLED) {
               program.properties.privateData[token] = blueArray;
@@ -623,12 +631,12 @@ var Type1Parser = function Type1ParserClosure() {
         }
       }
 
-      for (var i = 0; i < charstrings.length; i++) {
-        glyph = charstrings[i].glyph;
+      for (let i = 0; i < charstrings.length; i++) {
+        const glyph = charstrings[i].glyph;
         encoded = charstrings[i].encoded;
-        var charString = new Type1CharString();
-        var error = charString.convert(encoded, subrs, this.seacAnalysisEnabled);
-        var output = charString.output;
+        const charString = new Type1CharString();
+        const error = charString.convert(encoded, subrs, this.seacAnalysisEnabled);
+        let output = charString.output;
 
         if (error) {
           output = [14];
@@ -658,9 +666,10 @@ var Type1Parser = function Type1ParserClosure() {
       }
 
       return program;
-    },
-    extractFontHeader: function Type1Parser_extractFontHeader(properties) {
-      var token;
+    }
+
+    extractFontHeader(properties) {
+      let token;
 
       while ((token = this.getToken()) !== null) {
         if (token !== "/") {
@@ -671,22 +680,22 @@ var Type1Parser = function Type1ParserClosure() {
 
         switch (token) {
           case "FontMatrix":
-            var matrix = this.readNumberArray();
+            const matrix = this.readNumberArray();
             properties.fontMatrix = matrix;
             break;
 
           case "Encoding":
-            var encodingArg = this.getToken();
-            var encoding;
+            const encodingArg = this.getToken();
+            let encoding;
 
             if (!/^\d+$/.test(encodingArg)) {
               encoding = (0, _encodings.getEncoding)(encodingArg);
             } else {
               encoding = [];
-              var size = parseInt(encodingArg, 10) | 0;
+              const size = parseInt(encodingArg, 10) | 0;
               this.getToken();
 
-              for (var j = 0; j < size; j++) {
+              for (let j = 0; j < size; j++) {
                 token = this.getToken();
 
                 while (token !== "dup" && token !== "def") {
@@ -701,9 +710,9 @@ var Type1Parser = function Type1ParserClosure() {
                   break;
                 }
 
-                var index = this.readInt();
+                const index = this.readInt();
                 this.getToken();
-                var glyph = this.getToken();
+                const glyph = this.getToken();
                 encoding[index] = glyph;
                 this.getToken();
               }
@@ -713,7 +722,7 @@ var Type1Parser = function Type1ParserClosure() {
             break;
 
           case "FontBBox":
-            var fontBBox = this.readNumberArray();
+            const fontBBox = this.readNumberArray();
             properties.ascent = Math.max(fontBBox[3], fontBBox[1]);
             properties.descent = Math.min(fontBBox[1], fontBBox[3]);
             properties.ascentScaled = true;
@@ -721,7 +730,9 @@ var Type1Parser = function Type1ParserClosure() {
         }
       }
     }
-  };
+
+  }
+
   return Type1Parser;
 }();
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 10 - 10
lib/core/unicode.js


+ 21 - 10
lib/core/worker.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -107,7 +107,7 @@ class WorkerMessageHandler {
     var WorkerTasks = [];
     const verbosity = (0, _util.getVerbosityLevel)();
     const apiVersion = docParams.apiVersion;
-    const workerVersion = '2.7.570';
+    const workerVersion = '2.8.335';
 
     if (apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
@@ -124,7 +124,7 @@ class WorkerMessageHandler {
     }
 
     if (typeof ReadableStream === "undefined") {
-      throw new Error("The browser/environment lacks native support for critical " + "functionality used by the PDF.js library (e.g. `ReadableStream`); " + "please use an `es5`-build instead.");
+      throw new Error("The browser/environment lacks native support for critical " + "functionality used by the PDF.js library (e.g. `ReadableStream`); " + "please use a `legacy`-build instead.");
     }
 
     var docId = docParams.docId;
@@ -158,21 +158,22 @@ class WorkerMessageHandler {
         await pdfManager.ensureDoc("checkFirstPage");
       }
 
-      const [numPages, fingerprint] = await Promise.all([pdfManager.ensureDoc("numPages"), pdfManager.ensureDoc("fingerprint")]);
+      const [numPages, fingerprint, isPureXfa] = await Promise.all([pdfManager.ensureDoc("numPages"), pdfManager.ensureDoc("fingerprint"), pdfManager.ensureDoc("isPureXfa")]);
       return {
         numPages,
-        fingerprint
+        fingerprint,
+        isPureXfa
       };
     }
 
-    function getPdfManager(data, evaluatorOptions) {
+    function getPdfManager(data, evaluatorOptions, enableXfa) {
       var pdfManagerCapability = (0, _util.createPromiseCapability)();
       let newPdfManager;
       var source = data.source;
 
       if (source.data) {
         try {
-          newPdfManager = new _pdf_manager.LocalPdfManager(docId, source.data, source.password, evaluatorOptions, docBaseUrl);
+          newPdfManager = new _pdf_manager.LocalPdfManager(docId, source.data, source.password, evaluatorOptions, enableXfa, docBaseUrl);
           pdfManagerCapability.resolve(newPdfManager);
         } catch (ex) {
           pdfManagerCapability.reject(ex);
@@ -204,7 +205,7 @@ class WorkerMessageHandler {
           length: fullRequest.contentLength,
           disableAutoFetch,
           rangeChunkSize: source.rangeChunkSize
-        }, evaluatorOptions, docBaseUrl);
+        }, evaluatorOptions, enableXfa, docBaseUrl);
 
         for (let i = 0; i < cachedChunks.length; i++) {
           newPdfManager.sendProgressiveData(cachedChunks[i]);
@@ -227,7 +228,7 @@ class WorkerMessageHandler {
         }
 
         try {
-          newPdfManager = new _pdf_manager.LocalPdfManager(docId, pdfFile, source.password, evaluatorOptions, docBaseUrl);
+          newPdfManager = new _pdf_manager.LocalPdfManager(docId, pdfFile, source.password, evaluatorOptions, enableXfa, docBaseUrl);
           pdfManagerCapability.resolve(newPdfManager);
         } catch (ex) {
           pdfManagerCapability.reject(ex);
@@ -345,7 +346,7 @@ class WorkerMessageHandler {
         isEvalSupported: data.isEvalSupported,
         fontExtraProperties: data.fontExtraProperties
       };
-      getPdfManager(data, evaluatorOptions).then(function (newPdfManager) {
+      getPdfManager(data, evaluatorOptions, data.enableXfa).then(function (newPdfManager) {
         if (terminated) {
           newPdfManager.terminate(new _util.AbortException("Worker was terminated."));
           throw new Error("Worker was terminated");
@@ -416,6 +417,16 @@ class WorkerMessageHandler {
         return page.jsActions;
       });
     });
+    handler.on("GetPageXfa", function wphSetupGetXfa({
+      pageIndex
+    }) {
+      return pdfManager.getPage(pageIndex).then(function (page) {
+        return pdfManager.ensure(page, "xfaData");
+      });
+    });
+    handler.on("GetIsPureXfa", function wphSetupGetIsPureXfa(data) {
+      return pdfManager.ensureDoc("isPureXfa");
+    });
     handler.on("GetOutline", function wphSetupGetOutline(data) {
       return pdfManager.ensureCatalog("documentOutline");
     });

+ 1 - 1
lib/core/worker_stream.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

+ 2 - 2
lib/core/writer.js

@@ -2,7 +2,7 @@
  * @licstart The following is the entire license notice for the
  * Javascript code in this page
  *
- * Copyright 2020 Mozilla Foundation
+ * Copyright 2021 Mozilla Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ var _primitives = require("./primitives.js");
 
 var _core_utils = require("./core_utils.js");
 
-var _xml_parser = require("../shared/xml_parser.js");
+var _xml_parser = require("./xml_parser.js");
 
 var _crypto = require("./crypto.js");
 

+ 535 - 0
lib/core/xfa/bind.js

@@ -0,0 +1,535 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * Javascript code in this page
+ *
+ * Copyright 2021 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.Binder = void 0;
+
+var _xfa_object = require("./xfa_object.js");
+
+var _template = require("./template.js");
+
+var _som = require("./som.js");
+
+var _namespaces = require("./namespaces.js");
+
+var _util = require("../../shared/util.js");
+
+function createText(content) {
+  const node = new _template.Text({});
+  node[_xfa_object.$content] = content;
+  return node;
+}
+
+class Binder {
+  constructor(root) {
+    this.root = root;
+    this.datasets = root.datasets;
+
+    if (root.datasets && root.datasets.data) {
+      this.emptyMerge = false;
+      this.data = root.datasets.data;
+    } else {
+      this.emptyMerge = true;
+      this.data = new _xfa_object.XmlObject(_namespaces.NamespaceIds.datasets.id, "data");
+    }
+
+    this.root.form = this.form = root.template[_xfa_object.$clone]();
+  }
+
+  _isConsumeData() {
+    return !this.emptyMerge && this._mergeMode;
+  }
+
+  _isMatchTemplate() {
+    return !this._isConsumeData();
+  }
+
+  bind() {
+    this._bindElement(this.form, this.data);
+
+    return this.form;
+  }
+
+  getData() {
+    return this.data;
+  }
+
+  _bindValue(formNode, data, picture) {
+    if (formNode[_xfa_object.$hasSettableValue]()) {
+      if (data[_xfa_object.$isDataValue]()) {
+        const value = data[_xfa_object.$content].trim();
+
+        formNode[_xfa_object.$setValue](createText(value));
+
+        formNode[_xfa_object.$data] = data;
+      } else if (formNode instanceof _template.Field && formNode.ui && formNode.ui.choiceList && formNode.ui.choiceList.open === "multiSelect") {
+        const value = data[_xfa_object.$getChildren]().map(child => child[_xfa_object.$content].trim()).join("\n");
+
+        formNode[_xfa_object.$setValue](createText(value));
+
+        formNode[_xfa_object.$data] = data;
+      } else if (this._isConsumeData()) {
+        (0, _util.warn)(`XFA - Nodes haven't the same type.`);
+      }
+    } else if (!data[_xfa_object.$isDataValue]() || this._isMatchTemplate()) {
+      this._bindElement(formNode, data);
+
+      formNode[_xfa_object.$data] = data;
+    } else {
+      (0, _util.warn)(`XFA - Nodes haven't the same type.`);
+    }
+  }
+
+  _findDataByNameToConsume(name, dataNode, global) {
+    if (!name) {
+      return null;
+    }
+
+    let generator, match;
+
+    for (let i = 0; i < 3; i++) {
+      generator = dataNode[_xfa_object.$getRealChildrenByNameIt](name, false, true);
+      match = generator.next().value;
+
+      if (match) {
+        return match;
+      }
+
+      if (dataNode[_xfa_object.$namespaceId] === _namespaces.NamespaceIds.datasets.id && dataNode[_xfa_object.$nodeName] === "data") {
+        break;
+      }
+
+      dataNode = dataNode[_xfa_object.$getParent]();
+    }
+
+    if (!global) {
+      return null;
+    }
+
+    generator = this.datasets[_xfa_object.$getRealChildrenByNameIt](name, false, false);
+
+    while (true) {
+      match = generator.next().value;
+
+      if (!match) {
+        break;
+      }
+
+      if (match[_xfa_object.$global]) {
+        return match;
+      }
+    }
+
+    generator = this.data[_xfa_object.$getAttributeIt](name, true);
+    match = generator.next().value;
+
+    if (match && match[_xfa_object.$isDataValue]()) {
+      return match;
+    }
+
+    return null;
+  }
+
+  _setProperties(formNode, dataNode) {
+    if (!formNode.hasOwnProperty("setProperty")) {
+      return;
+    }
+
+    for (const {
+      ref,
+      target,
+      connection
+    } of formNode.setProperty.children) {
+      if (connection) {
+        continue;
+      }
+
+      if (!ref) {
+        continue;
+      }
+
+      const [node] = (0, _som.searchNode)(this.root, dataNode, ref, false, false);
+
+      if (!node) {
+        (0, _util.warn)(`XFA - Invalid reference: ${ref}.`);
+        continue;
+      }
+
+      if (!node[_xfa_object.$isDescendent](this.data)) {
+        (0, _util.warn)(`XFA - Invalid node: must be a data node.`);
+        continue;
+      }
+
+      const [targetNode] = (0, _som.searchNode)(this.root, formNode, target, false, false);
+
+      if (!targetNode) {
+        (0, _util.warn)(`XFA - Invalid target: ${target}.`);
+        continue;
+      }
+
+      if (!targetNode[_xfa_object.$isDescendent](formNode)) {
+        (0, _util.warn)(`XFA - Invalid target: must be a property or subproperty.`);
+        continue;
+      }
+
+      const targetParent = targetNode[_xfa_object.$getParent]();
+
+      if (targetNode instanceof _template.SetProperty || targetParent instanceof _template.SetProperty) {
+        (0, _util.warn)(`XFA - Invalid target: cannot be a setProperty or one of its properties.`);
+        continue;
+      }
+
+      if (targetNode instanceof _template.BindItems || targetParent instanceof _template.BindItems) {
+        (0, _util.warn)(`XFA - Invalid target: cannot be a bindItems or one of its properties.`);
+        continue;
+      }
+
+      const content = node[_xfa_object.$text]();
+
+      const name = targetNode[_xfa_object.$nodeName];
+
+      if (targetNode instanceof _xfa_object.XFAAttribute) {
+        const attrs = Object.create(null);
+        attrs[name] = content;
+        const obj = Reflect.construct(Object.getPrototypeOf(targetParent).constructor, [attrs]);
+        targetParent[name] = obj[name];
+        continue;
+      }
+
+      if (!targetNode.hasOwnProperty(_xfa_object.$content)) {
+        (0, _util.warn)(`XFA - Invalid node to use in setProperty`);
+        continue;
+      }
+
+      targetNode[_xfa_object.$data] = node;
+      targetNode[_xfa_object.$content] = content;
+
+      targetNode[_xfa_object.$finalize]();
+    }
+  }
+
+  _bindItems(formNode, dataNode) {
+    if (!formNode.hasOwnProperty("items") || !formNode.hasOwnProperty("bindItems") || formNode.bindItems.isEmpty()) {
+      return;
+    }
+
+    for (const item of formNode.items.children) {
+      formNode[_xfa_object.$removeChild](item);
+    }
+
+    formNode.items.clear();
+    const labels = new _template.Items({});
+    const values = new _template.Items({});
+
+    formNode[_xfa_object.$appendChild](labels);
+
+    formNode.items.push(labels);
+
+    formNode[_xfa_object.$appendChild](values);
+
+    formNode.items.push(values);
+
+    for (const {
+      ref,
+      labelRef,
+      valueRef,
+      connection
+    } of formNode.bindItems.children) {
+      if (connection) {
+        continue;
+      }
+
+      if (!ref) {
+        continue;
+      }
+
+      const nodes = (0, _som.searchNode)(this.root, dataNode, ref, false, false);
+
+      if (!nodes) {
+        (0, _util.warn)(`XFA - Invalid reference: ${ref}.`);
+        continue;
+      }
+
+      for (const node of nodes) {
+        if (!node[_xfa_object.$isDescendent](this.datasets)) {
+          (0, _util.warn)(`XFA - Invalid ref (${ref}): must be a datasets child.`);
+          continue;
+        }
+
+        const [labelNode] = (0, _som.searchNode)(this.root, node, labelRef, true, false);
+
+        if (!labelNode) {
+          (0, _util.warn)(`XFA - Invalid label: ${labelRef}.`);
+          continue;
+        }
+
+        if (!labelNode[_xfa_object.$isDescendent](this.datasets)) {
+          (0, _util.warn)(`XFA - Invalid label: must be a datasets child.`);
+          continue;
+        }
+
+        const [valueNode] = (0, _som.searchNode)(this.root, node, valueRef, true, false);
+
+        if (!valueNode) {
+          (0, _util.warn)(`XFA - Invalid value: ${valueRef}.`);
+          continue;
+        }
+
+        if (!valueNode[_xfa_object.$isDescendent](this.datasets)) {
+          (0, _util.warn)(`XFA - Invalid value: must be a datasets child.`);
+          continue;
+        }
+
+        const label = createText(labelNode[_xfa_object.$text]());
+        const value = createText(valueNode[_xfa_object.$text]());
+
+        labels[_xfa_object.$appendChild](label);
+
+        labels.text.push(label);
+
+        values[_xfa_object.$appendChild](value);
+
+        values.text.push(value);
+      }
+    }
+  }
+
+  _bindOccurrences(formNode, matches, picture) {
+    let baseClone;
+
+    if (matches.length > 1) {
+      baseClone = formNode[_xfa_object.$clone]();
+    }
+
+    this._bindValue(formNode, matches[0], picture);
+
+    this._setProperties(formNode, matches[0]);
+
+    this._bindItems(formNode, matches[0]);
+
+    if (matches.length === 1) {
+      return;
+    }
+
+    const parent = formNode[_xfa_object.$getParent]();
+
+    const name = formNode[_xfa_object.$nodeName];
+
+    const pos = parent[_xfa_object.$indexOf](formNode);
+
+    for (let i = 1, ii = matches.length; i < ii; i++) {
+      const match = matches[i];
+
+      const clone = baseClone[_xfa_object.$clone]();
+
+      clone.occur.min = 1;
+      clone.occur.max = 1;
+      clone.occur.initial = 1;
+      parent[name].push(clone);
+
+      parent[_xfa_object.$insertAt](pos + i, clone);
+
+      this._bindValue(clone, match, picture);
+
+      this._setProperties(clone, match);
+
+      this._bindItems(clone, match);
+    }
+  }
+
+  _createOccurrences(formNode) {
+    if (!this.emptyMerge) {
+      return;
+    }
+
+    const {
+      occur
+    } = formNode;
+
+    if (!occur || occur.initial <= 1) {
+      return;
+    }
+
+    const parent = formNode[_xfa_object.$getParent]();
+
+    const name = formNode[_xfa_object.$nodeName];
+
+    for (let i = 0, ii = occur.initial; i < ii; i++) {
+      const clone = formNode[_xfa_object.$clone]();
+
+      clone.occur.min = 1;
+      clone.occur.max = 1;
+      clone.occur.initial = 1;
+      parent[name].push(clone);
+
+      parent[_xfa_object.$appendChild](clone);
+    }
+  }
+
+  _getOccurInfo(formNode) {
+    const {
+      occur
+    } = formNode;
+    const dataName = formNode.name;
+
+    if (!occur || !dataName) {
+      return [1, 1];
+    }
+
+    const max = occur.max === -1 ? Infinity : occur.max;
+    return [occur.min, max];
+  }
+
+  _bindElement(formNode, dataNode) {
+    const uselessNodes = [];
+
+    this._createOccurrences(formNode);
+
+    for (const child of formNode[_xfa_object.$getChildren]()) {
+      if (child[_xfa_object.$data]) {
+        continue;
+      }
+
+      if (this._mergeMode === undefined && child[_xfa_object.$nodeName] === "subform") {
+        this._mergeMode = child.mergeMode === "consumeData";
+      }
+
+      let global = false;
+      let picture = null;
+      let ref = null;
+      let match = null;
+
+      if (child.bind) {
+        switch (child.bind.match) {
+          case "none":
+            continue;
+
+          case "global":
+            global = true;
+            break;
+
+          case "dataRef":
+            if (!child.bind.ref) {
+              (0, _util.warn)(`XFA - ref is empty in node ${child[_xfa_object.$nodeName]}.`);
+              continue;
+            }
+
+            ref = child.bind.ref;
+            break;
+
+          default:
+            break;
+        }
+
+        if (child.bind.picture) {
+          picture = child.bind.picture[_xfa_object.$content];
+        }
+      }
+
+      const [min, max] = this._getOccurInfo(child);
+
+      if (ref) {
+        match = (0, _som.searchNode)(this.root, dataNode, ref, true, false);
+
+        if (match === null) {
+          match = (0, _som.createDataNode)(this.data, dataNode, ref);
+
+          if (this._isConsumeData()) {
+            match[_xfa_object.$consumed] = true;
+          }
+
+          match = [match];
+        } else {
+          if (this._isConsumeData()) {
+            match = match.filter(node => !node[_xfa_object.$consumed]);
+          }
+
+          if (match.length > max) {
+            match = match.slice(0, max);
+          } else if (match.length === 0) {
+            match = null;
+          }
+
+          if (match && this._isConsumeData()) {
+            match.forEach(node => {
+              node[_xfa_object.$consumed] = true;
+            });
+          }
+        }
+      } else {
+        if (!child.name) {
+          this._bindElement(child, dataNode);
+
+          continue;
+        }
+
+        if (this._isConsumeData()) {
+          const matches = [];
+
+          while (matches.length < max) {
+            const found = this._findDataByNameToConsume(child.name, dataNode, global);
+
+            if (!found) {
+              break;
+            }
+
+            found[_xfa_object.$consumed] = true;
+            matches.push(found);
+          }
+
+          match = matches.length > 0 ? matches : null;
+        } else {
+          match = dataNode[_xfa_object.$getRealChildrenByNameIt](child.name, false, false).next().value;
+
+          if (!match) {
+            match = new _xfa_object.XmlObject(dataNode[_xfa_object.$namespaceId], child.name);
+
+            dataNode[_xfa_object.$appendChild](match);
+          }
+
+          match = [match];
+        }
+      }
+
+      if (match) {
+        if (match.length < min) {
+          (0, _util.warn)(`XFA - Must have at least ${min} occurrences: ${formNode[_xfa_object.$nodeName]}.`);
+          continue;
+        }
+
+        this._bindOccurrences(child, match, picture);
+      } else if (min > 0) {
+        this._bindElement(child, dataNode);
+      } else {
+        uselessNodes.push(child);
+      }
+    }
+
+    uselessNodes.forEach(node => node[_xfa_object.$getParent]()[_xfa_object.$removeChild](node));
+  }
+
+}
+
+exports.Binder = Binder;

+ 232 - 0
lib/core/xfa/builder.js

@@ -0,0 +1,232 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * Javascript code in this page
+ *
+ * Copyright 2021 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.Builder = void 0;
+
+var _namespaces = require("./namespaces.js");
+
+var _xfa_object = require("./xfa_object.js");
+
+var _setup = require("./setup.js");
+
+var _template = require("./template.js");
+
+var _unknown = require("./unknown.js");
+
+var _util = require("../../shared/util.js");
+
+const _ids = Symbol();
+
+class Root extends _xfa_object.XFAObject {
+  constructor(ids) {
+    super(-1, "root", Object.create(null));
+    this.element = null;
+    this[_ids] = ids;
+  }
+
+  [_xfa_object.$onChild](child) {
+    this.element = child;
+    return true;
+  }
+
+  [_xfa_object.$finalize]() {
+    super[_xfa_object.$finalize]();
+
+    if (this.element.template instanceof _template.Template) {
+      this.element.template[_xfa_object.$resolvePrototypes](this[_ids]);
+    }
+  }
+
+}
+
+class Empty extends _xfa_object.XFAObject {
+  constructor() {
+    super(-1, "", Object.create(null));
+  }
+
+  [_xfa_object.$onChild](_) {
+    return false;
+  }
+
+}
+
+class Builder {
+  constructor() {
+    this._namespaceStack = [];
+    this._namespacePrefixes = new Map();
+    this._namespaces = new Map();
+    this._nextNsId = Math.max(...Object.values(_namespaces.NamespaceIds).map(({
+      id
+    }) => id));
+    this._currentNamespace = new _unknown.UnknownNamespace(++this._nextNsId);
+  }
+
+  buildRoot(ids) {
+    return new Root(ids);
+  }
+
+  build({
+    nsPrefix,
+    name,
+    attributes,
+    namespace,
+    prefixes
+  }) {
+    const hasNamespaceDef = namespace !== null;
+
+    if (hasNamespaceDef) {
+      this._namespaceStack.push(this._currentNamespace);
+
+      this._currentNamespace = this._searchNamespace(namespace);
+    }
+
+    if (prefixes) {
+      this._addNamespacePrefix(prefixes);
+    }
+
+    if (attributes.hasOwnProperty(_xfa_object.$nsAttributes)) {
+      const dataTemplate = _setup.NamespaceSetUp.datasets;
+      const nsAttrs = attributes[_xfa_object.$nsAttributes];
+      let xfaAttrs = null;
+
+      for (const [ns, attrs] of Object.entries(nsAttrs)) {
+        const nsToUse = this._getNamespaceToUse(ns);
+
+        if (nsToUse === dataTemplate) {
+          xfaAttrs = {
+            xfa: attrs
+          };
+          break;
+        }
+      }
+
+      if (xfaAttrs) {
+        attributes[_xfa_object.$nsAttributes] = xfaAttrs;
+      } else {
+        delete attributes[_xfa_object.$nsAttributes];
+      }
+    }
+
+    const namespaceToUse = this._getNamespaceToUse(nsPrefix);
+
+    const node = namespaceToUse && namespaceToUse[_namespaces.$buildXFAObject](name, attributes) || new Empty();
+
+    if (hasNamespaceDef || prefixes) {
+      node[_xfa_object.$cleanup] = {
+        hasNamespace: hasNamespaceDef,
+        prefixes
+      };
+    }
+
+    return node;
+  }
+
+  _searchNamespace(nsName) {
+    let ns = this._namespaces.get(nsName);
+
+    if (ns) {
+      return ns;
+    }
+
+    for (const [name, {
+      check
+    }] of Object.entries(_namespaces.NamespaceIds)) {
+      if (check(nsName)) {
+        ns = _setup.NamespaceSetUp[name];
+
+        if (ns) {
+          this._namespaces.set(nsName, ns);
+
+          return ns;
+        }
+
+        break;
+      }
+    }
+
+    ns = new _unknown.UnknownNamespace(++this._nextNsId);
+
+    this._namespaces.set(nsName, ns);
+
+    return ns;
+  }
+
+  _addNamespacePrefix(prefixes) {
+    for (const {
+      prefix,
+      value
+    } of prefixes) {
+      const namespace = this._searchNamespace(value);
+
+      let prefixStack = this._namespacePrefixes.get(prefix);
+
+      if (!prefixStack) {
+        prefixStack = [];
+
+        this._namespacePrefixes.set(prefix, prefixStack);
+      }
+
+      prefixStack.push(namespace);
+    }
+  }
+
+  _getNamespaceToUse(prefix) {
+    if (!prefix) {
+      return this._currentNamespace;
+    }
+
+    const prefixStack = this._namespacePrefixes.get(prefix);
+
+    if (prefixStack && prefixStack.length > 0) {
+      return prefixStack[prefixStack.length - 1];
+    }
+
+    (0, _util.warn)(`Unknown namespace prefix: ${prefix}.`);
+    return null;
+  }
+
+  clean(data) {
+    const {
+      hasNamespace,
+      prefixes
+    } = data;
+
+    if (hasNamespace) {
+      this._currentNamespace = this._namespaceStack.pop();
+    }
+
+    if (prefixes) {
+      prefixes.forEach(({
+        prefix
+      }) => {
+        this._namespacePrefixes.get(prefix).pop();
+      });
+    }
+  }
+
+}
+
+exports.Builder = Builder;

+ 1905 - 0
lib/core/xfa/config.js

@@ -0,0 +1,1905 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * Javascript code in this page
+ *
+ * Copyright 2021 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.ConfigNamespace = void 0;
+
+var _namespaces = require("./namespaces.js");
+
+var _xfa_object = require("./xfa_object.js");
+
+var _utils = require("./utils.js");
+
+var _util = require("../../shared/util.js");
+
+const CONFIG_NS_ID = _namespaces.NamespaceIds.config.id;
+
+class Acrobat extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "acrobat", true);
+    this.acrobat7 = null;
+    this.autoSave = null;
+    this.common = null;
+    this.validate = null;
+    this.validateApprovalSignatures = null;
+    this.submitUrl = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class Acrobat7 extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "acrobat7", true);
+    this.dynamicRender = null;
+  }
+
+}
+
+class ADBE_JSConsole extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "ADBE_JSConsole", ["delegate", "Enable", "Disable"]);
+  }
+
+}
+
+class ADBE_JSDebugger extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "ADBE_JSDebugger", ["delegate", "Enable", "Disable"]);
+  }
+
+}
+
+class AddSilentPrint extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "addSilentPrint");
+  }
+
+}
+
+class AddViewerPreferences extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "addViewerPreferences");
+  }
+
+}
+
+class AdjustData extends _xfa_object.Option10 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "adjustData");
+  }
+
+}
+
+class AdobeExtensionLevel extends _xfa_object.IntegerObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "adobeExtensionLevel", 0, n => n >= 1 && n <= 8);
+  }
+
+}
+
+class Agent extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "agent", true);
+    this.name = attributes.name ? attributes.name.trim() : "";
+    this.common = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class AlwaysEmbed extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "alwaysEmbed");
+  }
+
+}
+
+class Amd extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "amd");
+  }
+
+}
+
+class Area extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "area");
+    this.level = (0, _utils.getInteger)({
+      data: attributes.level,
+      defaultValue: 0,
+      validator: n => n >= 1 && n <= 3
+    });
+    this.name = (0, _utils.getStringOption)(attributes.name, ["", "barcode", "coreinit", "deviceDriver", "font", "general", "layout", "merge", "script", "signature", "sourceSet", "templateCache"]);
+  }
+
+}
+
+class Attributes extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "attributes", ["preserve", "delegate", "ignore"]);
+  }
+
+}
+
+class AutoSave extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "autoSave", ["disabled", "enabled"]);
+  }
+
+}
+
+class Base extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "base");
+  }
+
+}
+
+class BatchOutput extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "batchOutput");
+    this.format = (0, _utils.getStringOption)(attributes.format, ["none", "concat", "zip", "zipCompress"]);
+  }
+
+}
+
+class BehaviorOverride extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "behaviorOverride");
+  }
+
+  [_xfa_object.$finalize]() {
+    this[_xfa_object.$content] = new Map(this[_xfa_object.$content].trim().split(/\s+/).filter(x => !!x && x.include(":")).map(x => x.split(":", 2)));
+  }
+
+}
+
+class Cache extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "cache", true);
+    this.templateCache = null;
+  }
+
+}
+
+class Change extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "change");
+  }
+
+}
+
+class Common extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "common", true);
+    this.data = null;
+    this.locale = null;
+    this.localeSet = null;
+    this.messaging = null;
+    this.suppressBanner = null;
+    this.template = null;
+    this.validationMessaging = null;
+    this.versionControl = null;
+    this.log = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class Compress extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "compress");
+    this.scope = (0, _utils.getStringOption)(attributes.scope, ["imageOnly", "document"]);
+  }
+
+}
+
+class CompressLogicalStructure extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "compressLogicalStructure");
+  }
+
+}
+
+class CompressObjectStream extends _xfa_object.Option10 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "compressObjectStream");
+  }
+
+}
+
+class Compression extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "compression", true);
+    this.compressLogicalStructure = null;
+    this.compressObjectStream = null;
+    this.level = null;
+    this.type = null;
+  }
+
+}
+
+class Config extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "config", true);
+    this.acrobat = null;
+    this.present = null;
+    this.trace = null;
+    this.agent = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class Conformance extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "conformance", ["A", "B"]);
+  }
+
+}
+
+class ContentCopy extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "contentCopy");
+  }
+
+}
+
+class Copies extends _xfa_object.IntegerObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "copies", 1, n => n >= 1);
+  }
+
+}
+
+class Creator extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "creator");
+  }
+
+}
+
+class CurrentPage extends _xfa_object.IntegerObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "currentPage", 0, n => n >= 0);
+  }
+
+}
+
+class Data extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "data", true);
+    this.adjustData = null;
+    this.attributes = null;
+    this.incrementalLoad = null;
+    this.outputXSL = null;
+    this.range = null;
+    this.record = null;
+    this.startNode = null;
+    this.uri = null;
+    this.window = null;
+    this.xsl = null;
+    this.excludeNS = new _xfa_object.XFAObjectArray();
+    this.transform = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class Debug extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "debug", true);
+    this.uri = null;
+  }
+
+}
+
+class DefaultTypeface extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "defaultTypeface");
+    this.writingScript = (0, _utils.getStringOption)(attributes.writingScript, ["*", "Arabic", "Cyrillic", "EastEuropeanRoman", "Greek", "Hebrew", "Japanese", "Korean", "Roman", "SimplifiedChinese", "Thai", "TraditionalChinese", "Vietnamese"]);
+  }
+
+}
+
+class Destination extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "destination", ["pdf", "pcl", "ps", "webClient", "zpl"]);
+  }
+
+}
+
+class DocumentAssembly extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "documentAssembly");
+  }
+
+}
+
+class Driver extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "driver", true);
+    this.name = attributes.name ? attributes.name.trim() : "";
+    this.fontInfo = null;
+    this.xdc = null;
+  }
+
+}
+
+class DuplexOption extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "duplexOption", ["simplex", "duplexFlipLongEdge", "duplexFlipShortEdge"]);
+  }
+
+}
+
+class DynamicRender extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "dynamicRender", ["forbidden", "required"]);
+  }
+
+}
+
+class Embed extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "embed");
+  }
+
+}
+
+class Encrypt extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "encrypt");
+  }
+
+}
+
+class Encryption extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "encryption", true);
+    this.encrypt = null;
+    this.encryptionLevel = null;
+    this.permissions = null;
+  }
+
+}
+
+class EncryptionLevel extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "encryptionLevel", ["40bit", "128bit"]);
+  }
+
+}
+
+class Enforce extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "enforce");
+  }
+
+}
+
+class Equate extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "equate");
+    this.force = (0, _utils.getInteger)({
+      data: attributes.force,
+      defaultValue: 1,
+      validator: n => n === 0
+    });
+    this.from = attributes.from || "";
+    this.to = attributes.to || "";
+  }
+
+}
+
+class EquateRange extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "equateRange");
+    this.from = attributes.from || "";
+    this.to = attributes.to || "";
+    this._unicodeRange = attributes.unicodeRange || "";
+  }
+
+  get unicodeRange() {
+    const ranges = [];
+    const unicodeRegex = /U\+([0-9a-fA-F]+)/;
+    const unicodeRange = this._unicodeRange;
+
+    for (let range of unicodeRange.split(",").map(x => x.trim()).filter(x => !!x)) {
+      range = range.split("-", 2).map(x => {
+        const found = x.match(unicodeRegex);
+
+        if (!found) {
+          return 0;
+        }
+
+        return parseInt(found[1], 16);
+      });
+
+      if (range.length === 1) {
+        range.push(range[0]);
+      }
+
+      ranges.push(range);
+    }
+
+    return (0, _util.shadow)(this, "unicodeRange", ranges);
+  }
+
+}
+
+class Exclude extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "exclude");
+  }
+
+  [_xfa_object.$finalize]() {
+    this[_xfa_object.$content] = this[_xfa_object.$content].trim().split(/\s+/).filter(x => x && ["calculate", "close", "enter", "exit", "initialize", "ready", "validate"].includes(x));
+  }
+
+}
+
+class ExcludeNS extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "excludeNS");
+  }
+
+}
+
+class FlipLabel extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "flipLabel", ["usePrinterSetting", "on", "off"]);
+  }
+
+}
+
+class FontInfo extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "fontInfo", true);
+    this.embed = null;
+    this.map = null;
+    this.subsetBelow = null;
+    this.alwaysEmbed = new _xfa_object.XFAObjectArray();
+    this.defaultTypeface = new _xfa_object.XFAObjectArray();
+    this.neverEmbed = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class FormFieldFilling extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "formFieldFilling");
+  }
+
+}
+
+class GroupParent extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "groupParent");
+  }
+
+}
+
+class IfEmpty extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "ifEmpty", ["dataValue", "dataGroup", "ignore", "remove"]);
+  }
+
+}
+
+class IncludeXDPContent extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "includeXDPContent");
+  }
+
+}
+
+class IncrementalLoad extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "incrementalLoad", ["none", "forwardOnly"]);
+  }
+
+}
+
+class IncrementalMerge extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "incrementalMerge");
+  }
+
+}
+
+class Interactive extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "interactive");
+  }
+
+}
+
+class Jog extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "jog", ["usePrinterSetting", "none", "pageSet"]);
+  }
+
+}
+
+class LabelPrinter extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "labelPrinter", true);
+    this.name = (0, _utils.getStringOption)(attributes.name, ["zpl", "dpl", "ipl", "tcpl"]);
+    this.batchOutput = null;
+    this.flipLabel = null;
+    this.fontInfo = null;
+    this.xdc = null;
+  }
+
+}
+
+class Layout extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "layout", ["paginate", "panel"]);
+  }
+
+}
+
+class Level extends _xfa_object.IntegerObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "level", 0, n => n > 0);
+  }
+
+}
+
+class Linearized extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "linearized");
+  }
+
+}
+
+class Locale extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "locale");
+  }
+
+}
+
+class LocaleSet extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "localeSet");
+  }
+
+}
+
+class Log extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "log", true);
+    this.mode = null;
+    this.threshold = null;
+    this.to = null;
+    this.uri = null;
+  }
+
+}
+
+class MapElement extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "map", true);
+    this.equate = new _xfa_object.XFAObjectArray();
+    this.equateRange = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class MediumInfo extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "mediumInfo", true);
+    this.map = null;
+  }
+
+}
+
+class Message extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "message", true);
+    this.msgId = null;
+    this.severity = null;
+  }
+
+}
+
+class Messaging extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "messaging", true);
+    this.message = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class Mode extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "mode", ["append", "overwrite"]);
+  }
+
+}
+
+class ModifyAnnots extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "modifyAnnots");
+  }
+
+}
+
+class MsgId extends _xfa_object.IntegerObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "msgId", 1, n => n >= 1);
+  }
+
+}
+
+class NameAttr extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "nameAttr");
+  }
+
+}
+
+class NeverEmbed extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "neverEmbed");
+  }
+
+}
+
+class NumberOfCopies extends _xfa_object.IntegerObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "numberOfCopies", null, n => n >= 2 && n <= 5);
+  }
+
+}
+
+class OpenAction extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "openAction", true);
+    this.destination = null;
+  }
+
+}
+
+class Output extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "output", true);
+    this.to = null;
+    this.type = null;
+    this.uri = null;
+  }
+
+}
+
+class OutputBin extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "outputBin");
+  }
+
+}
+
+class OutputXSL extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "outputXSL", true);
+    this.uri = null;
+  }
+
+}
+
+class Overprint extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "overprint", ["none", "both", "draw", "field"]);
+  }
+
+}
+
+class Packets extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "packets");
+  }
+
+  [_xfa_object.$finalize]() {
+    if (this[_xfa_object.$content] === "*") {
+      return;
+    }
+
+    this[_xfa_object.$content] = this[_xfa_object.$content].trim().split(/\s+/).filter(x => ["config", "datasets", "template", "xfdf", "xslt"].includes(x));
+  }
+
+}
+
+class PageOffset extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "pageOffset");
+    this.x = (0, _utils.getInteger)({
+      data: attributes.x,
+      defaultValue: "useXDCSetting",
+      validator: n => true
+    });
+    this.y = (0, _utils.getInteger)({
+      data: attributes.y,
+      defaultValue: "useXDCSetting",
+      validator: n => true
+    });
+  }
+
+}
+
+class PageRange extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "pageRange");
+  }
+
+  [_xfa_object.$finalize]() {
+    const numbers = this[_xfa_object.$content].trim().split(/\s+/).map(x => parseInt(x, 10));
+
+    const ranges = [];
+
+    for (let i = 0, ii = numbers.length; i < ii; i += 2) {
+      ranges.push(numbers.slice(i, i + 2));
+    }
+
+    this[_xfa_object.$content] = ranges;
+  }
+
+}
+
+class Pagination extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "pagination", ["simplex", "duplexShortEdge", "duplexLongEdge"]);
+  }
+
+}
+
+class PaginationOverride extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "paginationOverride", ["none", "forceDuplex", "forceDuplexLongEdge", "forceDuplexShortEdge", "forceSimplex"]);
+  }
+
+}
+
+class Part extends _xfa_object.IntegerObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "part", 1, n => false);
+  }
+
+}
+
+class Pcl extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "pcl", true);
+    this.name = attributes.name || "";
+    this.batchOutput = null;
+    this.fontInfo = null;
+    this.jog = null;
+    this.mediumInfo = null;
+    this.outputBin = null;
+    this.pageOffset = null;
+    this.staple = null;
+    this.xdc = null;
+  }
+
+}
+
+class Pdf extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "pdf", true);
+    this.name = attributes.name || "";
+    this.adobeExtensionLevel = null;
+    this.batchOutput = null;
+    this.compression = null;
+    this.creator = null;
+    this.encryption = null;
+    this.fontInfo = null;
+    this.interactive = null;
+    this.linearized = null;
+    this.openAction = null;
+    this.pdfa = null;
+    this.producer = null;
+    this.renderPolicy = null;
+    this.scriptModel = null;
+    this.silentPrint = null;
+    this.submitFormat = null;
+    this.tagged = null;
+    this.version = null;
+    this.viewerPreferences = null;
+    this.xdc = null;
+  }
+
+}
+
+class Pdfa extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "pdfa", true);
+    this.amd = null;
+    this.conformance = null;
+    this.includeXDPContent = null;
+    this.part = null;
+  }
+
+}
+
+class Permissions extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "permissions", true);
+    this.accessibleContent = null;
+    this.change = null;
+    this.contentCopy = null;
+    this.documentAssembly = null;
+    this.formFieldFilling = null;
+    this.modifyAnnots = null;
+    this.plaintextMetadata = null;
+    this.print = null;
+    this.printHighQuality = null;
+  }
+
+}
+
+class PickTrayByPDFSize extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "pickTrayByPDFSize");
+  }
+
+}
+
+class Picture extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "picture");
+  }
+
+}
+
+class PlaintextMetadata extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "plaintextMetadata");
+  }
+
+}
+
+class Presence extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "presence", ["preserve", "dissolve", "dissolveStructure", "ignore", "remove"]);
+  }
+
+}
+
+class Present extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "present", true);
+    this.behaviorOverride = null;
+    this.cache = null;
+    this.common = null;
+    this.copies = null;
+    this.destination = null;
+    this.incrementalMerge = null;
+    this.layout = null;
+    this.output = null;
+    this.overprint = null;
+    this.pagination = null;
+    this.paginationOverride = null;
+    this.script = null;
+    this.validate = null;
+    this.xdp = null;
+    this.driver = new _xfa_object.XFAObjectArray();
+    this.labelPrinter = new _xfa_object.XFAObjectArray();
+    this.pcl = new _xfa_object.XFAObjectArray();
+    this.pdf = new _xfa_object.XFAObjectArray();
+    this.ps = new _xfa_object.XFAObjectArray();
+    this.submitUrl = new _xfa_object.XFAObjectArray();
+    this.webClient = new _xfa_object.XFAObjectArray();
+    this.zpl = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class Print extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "print");
+  }
+
+}
+
+class PrintHighQuality extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "printHighQuality");
+  }
+
+}
+
+class PrintScaling extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "printScaling", ["appdefault", "noScaling"]);
+  }
+
+}
+
+class PrinterName extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "printerName");
+  }
+
+}
+
+class Producer extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "producer");
+  }
+
+}
+
+class Ps extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "ps", true);
+    this.name = attributes.name || "";
+    this.batchOutput = null;
+    this.fontInfo = null;
+    this.jog = null;
+    this.mediumInfo = null;
+    this.outputBin = null;
+    this.staple = null;
+    this.xdc = null;
+  }
+
+}
+
+class Range extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "range");
+  }
+
+  [_xfa_object.$finalize]() {
+    this[_xfa_object.$content] = this[_xfa_object.$content].trim().split(/\s*,\s*/, 2).map(range => range.split("-").map(x => parseInt(x.trim(), 10))).filter(range => range.every(x => !isNaN(x))).map(range => {
+      if (range.length === 1) {
+        range.push(range[0]);
+      }
+
+      return range;
+    });
+  }
+
+}
+
+class Record extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "record");
+  }
+
+  [_xfa_object.$finalize]() {
+    this[_xfa_object.$content] = this[_xfa_object.$content].trim();
+    const n = parseInt(this[_xfa_object.$content], 10);
+
+    if (!isNaN(n) && n >= 0) {
+      this[_xfa_object.$content] = n;
+    }
+  }
+
+}
+
+class Relevant extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "relevant");
+  }
+
+  [_xfa_object.$finalize]() {
+    this[_xfa_object.$content] = this[_xfa_object.$content].trim().split(/\s+/);
+  }
+
+}
+
+class Rename extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "rename");
+  }
+
+  [_xfa_object.$finalize]() {
+    this[_xfa_object.$content] = this[_xfa_object.$content].trim();
+
+    if (this[_xfa_object.$content].toLowerCase().startsWith("xml") || this[_xfa_object.$content].match(new RegExp("[\\p{L}_][\\p{L}\\d._\\p{M}-]*", "u"))) {
+      (0, _util.warn)("XFA - Rename: invalid XFA name");
+    }
+  }
+
+}
+
+class RenderPolicy extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "renderPolicy", ["server", "client"]);
+  }
+
+}
+
+class RunScripts extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "runScripts", ["both", "client", "none", "server"]);
+  }
+
+}
+
+class Script extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "script", true);
+    this.currentPage = null;
+    this.exclude = null;
+    this.runScripts = null;
+  }
+
+}
+
+class ScriptModel extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "scriptModel", ["XFA", "none"]);
+  }
+
+}
+
+class Severity extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "severity", ["ignore", "error", "information", "trace", "warning"]);
+  }
+
+}
+
+class SilentPrint extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "silentPrint", true);
+    this.addSilentPrint = null;
+    this.printerName = null;
+  }
+
+}
+
+class Staple extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "staple");
+    this.mode = (0, _utils.getStringOption)(attributes.mode, ["usePrinterSetting", "on", "off"]);
+  }
+
+}
+
+class StartNode extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "startNode");
+  }
+
+}
+
+class StartPage extends _xfa_object.IntegerObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "startPage", 0, n => true);
+  }
+
+}
+
+class SubmitFormat extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "submitFormat", ["html", "delegate", "fdf", "xml", "pdf"]);
+  }
+
+}
+
+class SubmitUrl extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "submitUrl");
+  }
+
+}
+
+class SubsetBelow extends _xfa_object.IntegerObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "subsetBelow", 100, n => n >= 0 && n <= 100);
+  }
+
+}
+
+class SuppressBanner extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "suppressBanner");
+  }
+
+}
+
+class Tagged extends _xfa_object.Option01 {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "tagged");
+  }
+
+}
+
+class Template extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "template", true);
+    this.base = null;
+    this.relevant = null;
+    this.startPage = null;
+    this.uri = null;
+    this.xsl = null;
+  }
+
+}
+
+class Threshold extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "threshold", ["trace", "error", "information", "warning"]);
+  }
+
+}
+
+class To extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "to", ["null", "memory", "stderr", "stdout", "system", "uri"]);
+  }
+
+}
+
+class TemplateCache extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "templateCache");
+    this.maxEntries = (0, _utils.getInteger)({
+      data: attributes.maxEntries,
+      defaultValue: 5,
+      validator: n => n >= 0
+    });
+  }
+
+}
+
+class Trace extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "trace", true);
+    this.area = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class Transform extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "transform", true);
+    this.groupParent = null;
+    this.ifEmpty = null;
+    this.nameAttr = null;
+    this.picture = null;
+    this.presence = null;
+    this.rename = null;
+    this.whitespace = null;
+  }
+
+}
+
+class Type extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "type", ["none", "ascii85", "asciiHex", "ccittfax", "flate", "lzw", "runLength", "native", "xdp", "mergedXDP"]);
+  }
+
+}
+
+class Uri extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "uri");
+  }
+
+}
+
+class Validate extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "validate", ["preSubmit", "prePrint", "preExecute", "preSave"]);
+  }
+
+}
+
+class ValidateApprovalSignatures extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "validateApprovalSignatures");
+  }
+
+  [_xfa_object.$finalize]() {
+    this[_xfa_object.$content] = this[_xfa_object.$content].trim().split(/\s+/).filter(x => ["docReady", "postSign"].includes(x));
+  }
+
+}
+
+class ValidationMessaging extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "validationMessaging", ["allMessagesIndividually", "allMessagesTogether", "firstMessageOnly", "noMessages"]);
+  }
+
+}
+
+class Version extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "version", ["1.7", "1.6", "1.5", "1.4", "1.3", "1.2"]);
+  }
+
+}
+
+class VersionControl extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "VersionControl");
+    this.outputBelow = (0, _utils.getStringOption)(attributes.outputBelow, ["warn", "error", "update"]);
+    this.sourceAbove = (0, _utils.getStringOption)(attributes.sourceAbove, ["warn", "error"]);
+    this.sourceBelow = (0, _utils.getStringOption)(attributes.sourceBelow, ["update", "maintain"]);
+  }
+
+}
+
+class ViewerPreferences extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "viewerPreferences", true);
+    this.ADBE_JSConsole = null;
+    this.ADBE_JSDebugger = null;
+    this.addViewerPreferences = null;
+    this.duplexOption = null;
+    this.enforce = null;
+    this.numberOfCopies = null;
+    this.pageRange = null;
+    this.pickTrayByPDFSize = null;
+    this.printScaling = null;
+  }
+
+}
+
+class WebClient extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "webClient", true);
+    this.name = attributes.name ? attributes.name.trim() : "";
+    this.fontInfo = null;
+    this.xdc = null;
+  }
+
+}
+
+class Whitespace extends _xfa_object.OptionObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "whitespace", ["preserve", "ltrim", "normalize", "rtrim", "trim"]);
+  }
+
+}
+
+class Window extends _xfa_object.ContentObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "window");
+  }
+
+  [_xfa_object.$finalize]() {
+    const pair = this[_xfa_object.$content].trim().split(/\s*,\s*/, 2).map(x => parseInt(x, 10));
+
+    if (pair.some(x => isNaN(x))) {
+      this[_xfa_object.$content] = [0, 0];
+      return;
+    }
+
+    if (pair.length === 1) {
+      pair.push(pair[0]);
+    }
+
+    this[_xfa_object.$content] = pair;
+  }
+
+}
+
+class Xdc extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "xdc", true);
+    this.uri = new _xfa_object.XFAObjectArray();
+    this.xsl = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class Xdp extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "xdp", true);
+    this.packets = null;
+  }
+
+}
+
+class Xsl extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "xsl", true);
+    this.debug = null;
+    this.uri = null;
+  }
+
+}
+
+class Zpl extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONFIG_NS_ID, "zpl", true);
+    this.name = attributes.name ? attributes.name.trim() : "";
+    this.batchOutput = null;
+    this.flipLabel = null;
+    this.fontInfo = null;
+    this.xdc = null;
+  }
+
+}
+
+class ConfigNamespace {
+  static [_namespaces.$buildXFAObject](name, attributes) {
+    if (ConfigNamespace.hasOwnProperty(name)) {
+      return ConfigNamespace[name](attributes);
+    }
+
+    return undefined;
+  }
+
+  static acrobat(attrs) {
+    return new Acrobat(attrs);
+  }
+
+  static acrobat7(attrs) {
+    return new Acrobat7(attrs);
+  }
+
+  static ADBE_JSConsole(attrs) {
+    return new ADBE_JSConsole(attrs);
+  }
+
+  static ADBE_JSDebugger(attrs) {
+    return new ADBE_JSDebugger(attrs);
+  }
+
+  static addSilentPrint(attrs) {
+    return new AddSilentPrint(attrs);
+  }
+
+  static addViewerPreferences(attrs) {
+    return new AddViewerPreferences(attrs);
+  }
+
+  static adjustData(attrs) {
+    return new AdjustData(attrs);
+  }
+
+  static adobeExtensionLevel(attrs) {
+    return new AdobeExtensionLevel(attrs);
+  }
+
+  static agent(attrs) {
+    return new Agent(attrs);
+  }
+
+  static alwaysEmbed(attrs) {
+    return new AlwaysEmbed(attrs);
+  }
+
+  static amd(attrs) {
+    return new Amd(attrs);
+  }
+
+  static area(attrs) {
+    return new Area(attrs);
+  }
+
+  static attributes(attrs) {
+    return new Attributes(attrs);
+  }
+
+  static autoSave(attrs) {
+    return new AutoSave(attrs);
+  }
+
+  static base(attrs) {
+    return new Base(attrs);
+  }
+
+  static batchOutput(attrs) {
+    return new BatchOutput(attrs);
+  }
+
+  static behaviorOverride(attrs) {
+    return new BehaviorOverride(attrs);
+  }
+
+  static cache(attrs) {
+    return new Cache(attrs);
+  }
+
+  static change(attrs) {
+    return new Change(attrs);
+  }
+
+  static common(attrs) {
+    return new Common(attrs);
+  }
+
+  static compress(attrs) {
+    return new Compress(attrs);
+  }
+
+  static compressLogicalStructure(attrs) {
+    return new CompressLogicalStructure(attrs);
+  }
+
+  static compressObjectStream(attrs) {
+    return new CompressObjectStream(attrs);
+  }
+
+  static compression(attrs) {
+    return new Compression(attrs);
+  }
+
+  static config(attrs) {
+    return new Config(attrs);
+  }
+
+  static conformance(attrs) {
+    return new Conformance(attrs);
+  }
+
+  static contentCopy(attrs) {
+    return new ContentCopy(attrs);
+  }
+
+  static copies(attrs) {
+    return new Copies(attrs);
+  }
+
+  static creator(attrs) {
+    return new Creator(attrs);
+  }
+
+  static currentPage(attrs) {
+    return new CurrentPage(attrs);
+  }
+
+  static data(attrs) {
+    return new Data(attrs);
+  }
+
+  static debug(attrs) {
+    return new Debug(attrs);
+  }
+
+  static defaultTypeface(attrs) {
+    return new DefaultTypeface(attrs);
+  }
+
+  static destination(attrs) {
+    return new Destination(attrs);
+  }
+
+  static documentAssembly(attrs) {
+    return new DocumentAssembly(attrs);
+  }
+
+  static driver(attrs) {
+    return new Driver(attrs);
+  }
+
+  static duplexOption(attrs) {
+    return new DuplexOption(attrs);
+  }
+
+  static dynamicRender(attrs) {
+    return new DynamicRender(attrs);
+  }
+
+  static embed(attrs) {
+    return new Embed(attrs);
+  }
+
+  static encrypt(attrs) {
+    return new Encrypt(attrs);
+  }
+
+  static encryption(attrs) {
+    return new Encryption(attrs);
+  }
+
+  static encryptionLevel(attrs) {
+    return new EncryptionLevel(attrs);
+  }
+
+  static enforce(attrs) {
+    return new Enforce(attrs);
+  }
+
+  static equate(attrs) {
+    return new Equate(attrs);
+  }
+
+  static equateRange(attrs) {
+    return new EquateRange(attrs);
+  }
+
+  static exclude(attrs) {
+    return new Exclude(attrs);
+  }
+
+  static excludeNS(attrs) {
+    return new ExcludeNS(attrs);
+  }
+
+  static flipLabel(attrs) {
+    return new FlipLabel(attrs);
+  }
+
+  static fontInfo(attrs) {
+    return new FontInfo(attrs);
+  }
+
+  static formFieldFilling(attrs) {
+    return new FormFieldFilling(attrs);
+  }
+
+  static groupParent(attrs) {
+    return new GroupParent(attrs);
+  }
+
+  static ifEmpty(attrs) {
+    return new IfEmpty(attrs);
+  }
+
+  static includeXDPContent(attrs) {
+    return new IncludeXDPContent(attrs);
+  }
+
+  static incrementalLoad(attrs) {
+    return new IncrementalLoad(attrs);
+  }
+
+  static incrementalMerge(attrs) {
+    return new IncrementalMerge(attrs);
+  }
+
+  static interactive(attrs) {
+    return new Interactive(attrs);
+  }
+
+  static jog(attrs) {
+    return new Jog(attrs);
+  }
+
+  static labelPrinter(attrs) {
+    return new LabelPrinter(attrs);
+  }
+
+  static layout(attrs) {
+    return new Layout(attrs);
+  }
+
+  static level(attrs) {
+    return new Level(attrs);
+  }
+
+  static linearized(attrs) {
+    return new Linearized(attrs);
+  }
+
+  static locale(attrs) {
+    return new Locale(attrs);
+  }
+
+  static localeSet(attrs) {
+    return new LocaleSet(attrs);
+  }
+
+  static log(attrs) {
+    return new Log(attrs);
+  }
+
+  static map(attrs) {
+    return new MapElement(attrs);
+  }
+
+  static mediumInfo(attrs) {
+    return new MediumInfo(attrs);
+  }
+
+  static message(attrs) {
+    return new Message(attrs);
+  }
+
+  static messaging(attrs) {
+    return new Messaging(attrs);
+  }
+
+  static mode(attrs) {
+    return new Mode(attrs);
+  }
+
+  static modifyAnnots(attrs) {
+    return new ModifyAnnots(attrs);
+  }
+
+  static msgId(attrs) {
+    return new MsgId(attrs);
+  }
+
+  static nameAttr(attrs) {
+    return new NameAttr(attrs);
+  }
+
+  static neverEmbed(attrs) {
+    return new NeverEmbed(attrs);
+  }
+
+  static numberOfCopies(attrs) {
+    return new NumberOfCopies(attrs);
+  }
+
+  static openAction(attrs) {
+    return new OpenAction(attrs);
+  }
+
+  static output(attrs) {
+    return new Output(attrs);
+  }
+
+  static outputBin(attrs) {
+    return new OutputBin(attrs);
+  }
+
+  static outputXSL(attrs) {
+    return new OutputXSL(attrs);
+  }
+
+  static overprint(attrs) {
+    return new Overprint(attrs);
+  }
+
+  static packets(attrs) {
+    return new Packets(attrs);
+  }
+
+  static pageOffset(attrs) {
+    return new PageOffset(attrs);
+  }
+
+  static pageRange(attrs) {
+    return new PageRange(attrs);
+  }
+
+  static pagination(attrs) {
+    return new Pagination(attrs);
+  }
+
+  static paginationOverride(attrs) {
+    return new PaginationOverride(attrs);
+  }
+
+  static part(attrs) {
+    return new Part(attrs);
+  }
+
+  static pcl(attrs) {
+    return new Pcl(attrs);
+  }
+
+  static pdf(attrs) {
+    return new Pdf(attrs);
+  }
+
+  static pdfa(attrs) {
+    return new Pdfa(attrs);
+  }
+
+  static permissions(attrs) {
+    return new Permissions(attrs);
+  }
+
+  static pickTrayByPDFSize(attrs) {
+    return new PickTrayByPDFSize(attrs);
+  }
+
+  static picture(attrs) {
+    return new Picture(attrs);
+  }
+
+  static plaintextMetadata(attrs) {
+    return new PlaintextMetadata(attrs);
+  }
+
+  static presence(attrs) {
+    return new Presence(attrs);
+  }
+
+  static present(attrs) {
+    return new Present(attrs);
+  }
+
+  static print(attrs) {
+    return new Print(attrs);
+  }
+
+  static printHighQuality(attrs) {
+    return new PrintHighQuality(attrs);
+  }
+
+  static printScaling(attrs) {
+    return new PrintScaling(attrs);
+  }
+
+  static printerName(attrs) {
+    return new PrinterName(attrs);
+  }
+
+  static producer(attrs) {
+    return new Producer(attrs);
+  }
+
+  static ps(attrs) {
+    return new Ps(attrs);
+  }
+
+  static range(attrs) {
+    return new Range(attrs);
+  }
+
+  static record(attrs) {
+    return new Record(attrs);
+  }
+
+  static relevant(attrs) {
+    return new Relevant(attrs);
+  }
+
+  static rename(attrs) {
+    return new Rename(attrs);
+  }
+
+  static renderPolicy(attrs) {
+    return new RenderPolicy(attrs);
+  }
+
+  static runScripts(attrs) {
+    return new RunScripts(attrs);
+  }
+
+  static script(attrs) {
+    return new Script(attrs);
+  }
+
+  static scriptModel(attrs) {
+    return new ScriptModel(attrs);
+  }
+
+  static severity(attrs) {
+    return new Severity(attrs);
+  }
+
+  static silentPrint(attrs) {
+    return new SilentPrint(attrs);
+  }
+
+  static staple(attrs) {
+    return new Staple(attrs);
+  }
+
+  static startNode(attrs) {
+    return new StartNode(attrs);
+  }
+
+  static startPage(attrs) {
+    return new StartPage(attrs);
+  }
+
+  static submitFormat(attrs) {
+    return new SubmitFormat(attrs);
+  }
+
+  static submitUrl(attrs) {
+    return new SubmitUrl(attrs);
+  }
+
+  static subsetBelow(attrs) {
+    return new SubsetBelow(attrs);
+  }
+
+  static suppressBanner(attrs) {
+    return new SuppressBanner(attrs);
+  }
+
+  static tagged(attrs) {
+    return new Tagged(attrs);
+  }
+
+  static template(attrs) {
+    return new Template(attrs);
+  }
+
+  static templateCache(attrs) {
+    return new TemplateCache(attrs);
+  }
+
+  static threshold(attrs) {
+    return new Threshold(attrs);
+  }
+
+  static to(attrs) {
+    return new To(attrs);
+  }
+
+  static trace(attrs) {
+    return new Trace(attrs);
+  }
+
+  static transform(attrs) {
+    return new Transform(attrs);
+  }
+
+  static type(attrs) {
+    return new Type(attrs);
+  }
+
+  static uri(attrs) {
+    return new Uri(attrs);
+  }
+
+  static validate(attrs) {
+    return new Validate(attrs);
+  }
+
+  static validateApprovalSignatures(attrs) {
+    return new ValidateApprovalSignatures(attrs);
+  }
+
+  static validationMessaging(attrs) {
+    return new ValidationMessaging(attrs);
+  }
+
+  static version(attrs) {
+    return new Version(attrs);
+  }
+
+  static versionControl(attrs) {
+    return new VersionControl(attrs);
+  }
+
+  static viewerPreferences(attrs) {
+    return new ViewerPreferences(attrs);
+  }
+
+  static webClient(attrs) {
+    return new WebClient(attrs);
+  }
+
+  static whitespace(attrs) {
+    return new Whitespace(attrs);
+  }
+
+  static window(attrs) {
+    return new Window(attrs);
+  }
+
+  static xdc(attrs) {
+    return new Xdc(attrs);
+  }
+
+  static xdp(attrs) {
+    return new Xdp(attrs);
+  }
+
+  static xsl(attrs) {
+    return new Xsl(attrs);
+  }
+
+  static zpl(attrs) {
+    return new Zpl(attrs);
+  }
+
+}
+
+exports.ConfigNamespace = ConfigNamespace;

+ 230 - 0
lib/core/xfa/connection_set.js

@@ -0,0 +1,230 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * Javascript code in this page
+ *
+ * Copyright 2021 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.ConnectionSetNamespace = void 0;
+
+var _namespaces = require("./namespaces.js");
+
+var _xfa_object = require("./xfa_object.js");
+
+const CONNECTION_SET_NS_ID = _namespaces.NamespaceIds.connectionSet.id;
+
+class ConnectionSet extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "connectionSet", true);
+    this.wsdlConnection = new _xfa_object.XFAObjectArray();
+    this.xmlConnection = new _xfa_object.XFAObjectArray();
+    this.xsdConnection = new _xfa_object.XFAObjectArray();
+  }
+
+}
+
+class EffectiveInputPolicy extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "effectiveInputPolicy");
+    this.id = attributes.id || "";
+    this.name = attributes.name || "";
+    this.use = attributes.use || "";
+    this.usehref = attributes.usehref || "";
+  }
+
+}
+
+class EffectiveOutputPolicy extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "effectiveOutputPolicy");
+    this.id = attributes.id || "";
+    this.name = attributes.name || "";
+    this.use = attributes.use || "";
+    this.usehref = attributes.usehref || "";
+  }
+
+}
+
+class Operation extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "operation");
+    this.id = attributes.id || "";
+    this.input = attributes.input || "";
+    this.name = attributes.name || "";
+    this.output = attributes.output || "";
+    this.use = attributes.use || "";
+    this.usehref = attributes.usehref || "";
+  }
+
+}
+
+class RootElement extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "rootElement");
+    this.id = attributes.id || "";
+    this.name = attributes.name || "";
+    this.use = attributes.use || "";
+    this.usehref = attributes.usehref || "";
+  }
+
+}
+
+class SoapAction extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "soapAction");
+    this.id = attributes.id || "";
+    this.name = attributes.name || "";
+    this.use = attributes.use || "";
+    this.usehref = attributes.usehref || "";
+  }
+
+}
+
+class SoapAddress extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "soapAddress");
+    this.id = attributes.id || "";
+    this.name = attributes.name || "";
+    this.use = attributes.use || "";
+    this.usehref = attributes.usehref || "";
+  }
+
+}
+
+class Uri extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "uri");
+    this.id = attributes.id || "";
+    this.name = attributes.name || "";
+    this.use = attributes.use || "";
+    this.usehref = attributes.usehref || "";
+  }
+
+}
+
+class WsdlAddress extends _xfa_object.StringObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "wsdlAddress");
+    this.id = attributes.id || "";
+    this.name = attributes.name || "";
+    this.use = attributes.use || "";
+    this.usehref = attributes.usehref || "";
+  }
+
+}
+
+class WsdlConnection extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "wsdlConnection", true);
+    this.dataDescription = attributes.dataDescription || "";
+    this.name = attributes.name || "";
+    this.effectiveInputPolicy = null;
+    this.effectiveOutputPolicy = null;
+    this.operation = null;
+    this.soapAction = null;
+    this.soapAddress = null;
+    this.wsdlAddress = null;
+  }
+
+}
+
+class XmlConnection extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "xmlConnection", true);
+    this.dataDescription = attributes.dataDescription || "";
+    this.name = attributes.name || "";
+    this.uri = null;
+  }
+
+}
+
+class XsdConnection extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(CONNECTION_SET_NS_ID, "xsdConnection", true);
+    this.dataDescription = attributes.dataDescription || "";
+    this.name = attributes.name || "";
+    this.rootElement = null;
+    this.uri = null;
+  }
+
+}
+
+class ConnectionSetNamespace {
+  static [_namespaces.$buildXFAObject](name, attributes) {
+    if (ConnectionSetNamespace.hasOwnProperty(name)) {
+      return ConnectionSetNamespace[name](attributes);
+    }
+
+    return undefined;
+  }
+
+  static connectionSet(attrs) {
+    return new ConnectionSet(attrs);
+  }
+
+  static effectiveInputPolicy(attrs) {
+    return new EffectiveInputPolicy(attrs);
+  }
+
+  static effectiveOutputPolicy(attrs) {
+    return new EffectiveOutputPolicy(attrs);
+  }
+
+  static operation(attrs) {
+    return new Operation(attrs);
+  }
+
+  static rootElement(attrs) {
+    return new RootElement(attrs);
+  }
+
+  static soapAction(attrs) {
+    return new SoapAction(attrs);
+  }
+
+  static soapAddress(attrs) {
+    return new SoapAddress(attrs);
+  }
+
+  static uri(attrs) {
+    return new Uri(attrs);
+  }
+
+  static wsdlAddress(attrs) {
+    return new WsdlAddress(attrs);
+  }
+
+  static wsdlConnection(attrs) {
+    return new WsdlConnection(attrs);
+  }
+
+  static xmlConnection(attrs) {
+    return new XmlConnection(attrs);
+  }
+
+  static xsdConnection(attrs) {
+    return new XsdConnection(attrs);
+  }
+
+}
+
+exports.ConnectionSetNamespace = ConnectionSetNamespace;

+ 82 - 0
lib/core/xfa/datasets.js

@@ -0,0 +1,82 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * Javascript code in this page
+ *
+ * Copyright 2021 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.DatasetsNamespace = void 0;
+
+var _xfa_object = require("./xfa_object.js");
+
+var _namespaces = require("./namespaces.js");
+
+const DATASETS_NS_ID = _namespaces.NamespaceIds.datasets.id;
+
+class Data extends _xfa_object.XmlObject {
+  constructor(attributes) {
+    super(DATASETS_NS_ID, "data", attributes);
+  }
+
+}
+
+class Datasets extends _xfa_object.XFAObject {
+  constructor(attributes) {
+    super(DATASETS_NS_ID, "datasets", true);
+    this.data = null;
+    this.Signature = null;
+  }
+
+  [_xfa_object.$onChild](child) {
+    const name = child[_xfa_object.$nodeName];
+
+    if (name === "data" && child[_xfa_object.$namespaceId] === DATASETS_NS_ID || name === "Signature" && child[_xfa_object.$namespaceId] === _namespaces.NamespaceIds.signature.id) {
+      this[name] = child;
+    } else {
+      child[_xfa_object.$global] = true;
+    }
+
+    this[_xfa_object.$appendChild](child);
+  }
+
+}
+
+class DatasetsNamespace {
+  static [_namespaces.$buildXFAObject](name, attributes) {
+    if (DatasetsNamespace.hasOwnProperty(name)) {
+      return DatasetsNamespace[name](attributes);
+    }
+
+    return undefined;
+  }
+
+  static datasets(attributes) {
+    return new Datasets(attributes);
+  }
+
+  static data(attributes) {
+    return new Data(attributes);
+  }
+
+}
+
+exports.DatasetsNamespace = DatasetsNamespace;

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels