Преглед изворни кода

PDF.js version 3.1.81 - See https://github.com/mozilla/pdf.js/releases/tag/v3.1.81

pdfjsbot пре 2 година
родитељ
комит
eb245b8de8
85 измењених фајлова са 4062 додато и 3329 уклоњено
  1. 86 89
      build/pdf.js
  2. 0 0
      build/pdf.js.map
  3. 0 0
      build/pdf.min.js
  4. 2 2
      build/pdf.sandbox.js
  5. 0 0
      build/pdf.sandbox.js.map
  6. 0 0
      build/pdf.sandbox.min.js
  7. 321 196
      build/pdf.worker.js
  8. 0 0
      build/pdf.worker.js.map
  9. 0 0
      build/pdf.worker.min.js
  10. 57 29
      image_decoders/pdf.image_decoders.js
  11. 0 0
      image_decoders/pdf.image_decoders.js.map
  12. 0 0
      image_decoders/pdf.image_decoders.min.js
  13. 195 226
      legacy/build/pdf.js
  14. 0 0
      legacy/build/pdf.js.map
  15. 0 0
      legacy/build/pdf.min.js
  16. 2 2
      legacy/build/pdf.sandbox.js
  17. 0 0
      legacy/build/pdf.sandbox.js.map
  18. 0 0
      legacy/build/pdf.sandbox.min.js
  19. 190 219
      legacy/build/pdf.worker.js
  20. 0 0
      legacy/build/pdf.worker.js.map
  21. 0 0
      legacy/build/pdf.worker.min.js
  22. 194 225
      legacy/image_decoders/pdf.image_decoders.js
  23. 0 0
      legacy/image_decoders/pdf.image_decoders.js.map
  24. 0 0
      legacy/image_decoders/pdf.image_decoders.min.js
  25. 949 889
      legacy/web/pdf_viewer.js
  26. 0 0
      legacy/web/pdf_viewer.js.map
  27. 338 219
      lib/core/annotation.js
  28. 7 0
      lib/core/catalog.js
  29. 49 0
      lib/core/core_utils.js
  30. 197 2
      lib/core/default_appearance.js
  31. 15 11
      lib/core/evaluator.js
  32. 20 11
      lib/core/fonts.js
  33. 22 20
      lib/core/parser.js
  34. 46 44
      lib/core/worker.js
  35. 54 37
      lib/core/writer.js
  36. 30 9
      lib/core/xref.js
  37. 10 7
      lib/display/annotation_layer.js
  38. 18 18
      lib/display/annotation_storage.js
  39. 6 4
      lib/display/api.js
  40. 23 4
      lib/display/canvas.js
  41. 17 17
      lib/display/display_utils.js
  42. 1 6
      lib/display/editor/freetext.js
  43. 2 1
      lib/display/text_layer.js
  44. 2 2
      lib/pdf.js
  45. 2 2
      lib/pdf.sandbox.js
  46. 2 2
      lib/pdf.worker.js
  47. 1 3
      lib/shared/murmurhash3.js
  48. 6 27
      lib/shared/util.js
  49. 33 30
      lib/test/unit/annotation_spec.js
  50. 37 9
      lib/test/unit/api_spec.js
  51. 28 0
      lib/test/unit/core_utils_spec.js
  52. 4 0
      lib/test/unit/display_utils_spec.js
  53. 5 0
      lib/test/unit/document_spec.js
  54. 20 0
      lib/test/unit/pdf_find_controller_spec.js
  55. 16 7
      lib/test/unit/test_utils.js
  56. 0 18
      lib/test/unit/util_spec.js
  57. 2 2
      lib/test/unit/writer_spec.js
  58. 37 0
      lib/web/annotation_layer_builder.js
  59. 3 0
      lib/web/app.js
  60. 4 6
      lib/web/download_manager.js
  61. 4 6
      lib/web/event_utils.js
  62. 4 6
      lib/web/firefoxcom.js
  63. 1 0
      lib/web/interfaces.js
  64. 1 1
      lib/web/pdf_attachment_viewer.js
  65. 30 14
      lib/web/pdf_find_controller.js
  66. 6 0
      lib/web/pdf_link_service.js
  67. 11 10
      lib/web/pdf_presentation_mode.js
  68. 2 2
      lib/web/pdf_viewer.component.js
  69. 7 2
      lib/web/pdf_viewer.js
  70. 4 2
      package.json
  71. 3 3
      types/src/display/annotation_layer.d.ts
  72. 3 14
      types/src/display/annotation_storage.d.ts
  73. 5 2
      types/src/display/canvas.d.ts
  74. 2 1
      types/src/display/display_utils.d.ts
  75. 0 1
      types/src/display/text_layer.d.ts
  76. 3 4
      types/src/shared/util.d.ts
  77. 2 0
      types/web/annotation_layer_builder.d.ts
  78. 1 1
      types/web/download_manager.d.ts
  79. 1 1
      types/web/event_utils.d.ts
  80. 4 0
      types/web/interfaces.d.ts
  81. 9 1
      types/web/pdf_link_service.d.ts
  82. 1 1
      types/web/pdf_thumbnail_view.d.ts
  83. 1 1
      types/web/text_accessibility.d.ts
  84. 904 861
      web/pdf_viewer.js
  85. 0 0
      web/pdf_viewer.js.map

+ 86 - 89
build/pdf.js

@@ -42,20 +42,18 @@ return /******/ (() => { // webpackBootstrap
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMode = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;
+exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.BASELINE_FACTOR = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMode = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;
 exports.arrayByteLength = arrayByteLength;
 exports.arraysToBytes = arraysToBytes;
 exports.assert = assert;
 exports.bytesToString = bytesToString;
 exports.createPromiseCapability = createPromiseCapability;
 exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
-exports.escapeString = escapeString;
 exports.getModificationDate = getModificationDate;
 exports.getVerbosityLevel = getVerbosityLevel;
 exports.info = info;
 exports.isArrayBuffer = isArrayBuffer;
 exports.isArrayEqual = isArrayEqual;
-exports.isAscii = isAscii;
 exports.objectFromMap = objectFromMap;
 exports.objectSize = objectSize;
 exports.setVerbosityLevel = setVerbosityLevel;
@@ -63,7 +61,6 @@ exports.shadow = shadow;
 exports.string32 = string32;
 exports.stringToBytes = stringToBytes;
 exports.stringToPDFString = stringToPDFString;
-exports.stringToUTF16BEString = stringToUTF16BEString;
 exports.stringToUTF8String = stringToUTF8String;
 exports.unreachable = unreachable;
 exports.utf8StringToString = utf8StringToString;
@@ -77,10 +74,13 @@ const LINE_FACTOR = 1.35;
 exports.LINE_FACTOR = LINE_FACTOR;
 const LINE_DESCENT_FACTOR = 0.35;
 exports.LINE_DESCENT_FACTOR = LINE_DESCENT_FACTOR;
+const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR;
+exports.BASELINE_FACTOR = BASELINE_FACTOR;
 const RenderingIntentFlag = {
   ANY: 0x01,
   DISPLAY: 0x02,
   PRINT: 0x04,
+  SAVE: 0x08,
   ANNOTATIONS_FORMS: 0x10,
   ANNOTATIONS_STORAGE: 0x20,
   ANNOTATIONS_DISABLE: 0x40,
@@ -492,10 +492,10 @@ function createValidAbsoluteUrl(url, baseUrl = null, options = null) {
   } catch (ex) {}
   return null;
 }
-function shadow(obj, prop, value) {
+function shadow(obj, prop, value, nonSerializable = false) {
   Object.defineProperty(obj, prop, {
     value,
-    enumerable: true,
+    enumerable: !nonSerializable,
     configurable: true,
     writable: false
   });
@@ -858,27 +858,6 @@ function stringToPDFString(str) {
   }
   return strBuf.join("");
 }
-function escapeString(str) {
-  return str.replace(/([()\\\n\r])/g, match => {
-    if (match === "\n") {
-      return "\\n";
-    } else if (match === "\r") {
-      return "\\r";
-    }
-    return `\\${match}`;
-  });
-}
-function isAscii(str) {
-  return /^[\x00-\x7F]*$/.test(str);
-}
-function stringToUTF16BEString(str) {
-  const buf = ["\xFE\xFF"];
-  for (let i = 0, ii = str.length; i < ii; i++) {
-    const char = str.charCodeAt(i);
-    buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff));
-  }
-  return buf.join("");
-}
 function stringToUTF8String(str) {
   return decodeURIComponent(escape(str));
 }
@@ -1149,7 +1128,7 @@ async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
   }
   const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", {
     docId,
-    apiVersion: '3.0.279',
+    apiVersion: '3.1.81',
     data: source.data,
     password: source.password,
     disableAutoFetch: source.disableAutoFetch,
@@ -2738,7 +2717,9 @@ class InternalRenderTask {
       transform,
       background
     } = this.params;
-    this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, optionalContentConfig, this.annotationCanvasMap, this.pageColors);
+    this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, {
+      optionalContentConfig
+    }, this.annotationCanvasMap, this.pageColors);
     this.gfx.beginDrawing({
       transform,
       viewport,
@@ -2808,9 +2789,9 @@ class InternalRenderTask {
     }
   }
 }
-const version = '3.0.279';
+const version = '3.1.81';
 exports.version = version;
-const build = 'd0823066c';
+const build = '0766898d5';
 exports.build = build;
 
 /***/ }),
@@ -2827,30 +2808,30 @@ var _util = __w_pdfjs_require__(1);
 var _editor = __w_pdfjs_require__(4);
 var _murmurhash = __w_pdfjs_require__(8);
 class AnnotationStorage {
+  #modified = false;
+  #storage = new Map();
   constructor() {
-    this._storage = new Map();
-    this._modified = false;
     this.onSetModified = null;
     this.onResetModified = null;
     this.onAnnotationEditor = null;
   }
   getValue(key, defaultValue) {
-    const value = this._storage.get(key);
+    const value = this.#storage.get(key);
     if (value === undefined) {
       return defaultValue;
     }
     return Object.assign(defaultValue, value);
   }
   getRawValue(key) {
-    return this._storage.get(key);
+    return this.#storage.get(key);
   }
   remove(key) {
-    this._storage.delete(key);
-    if (this._storage.size === 0) {
+    this.#storage.delete(key);
+    if (this.#storage.size === 0) {
       this.resetModified();
     }
     if (typeof this.onAnnotationEditor === "function") {
-      for (const value of this._storage.values()) {
+      for (const value of this.#storage.values()) {
         if (value instanceof _editor.AnnotationEditor) {
           return;
         }
@@ -2859,7 +2840,7 @@ class AnnotationStorage {
     }
   }
   setValue(key, value) {
-    const obj = this._storage.get(key);
+    const obj = this.#storage.get(key);
     let modified = false;
     if (obj !== undefined) {
       for (const [entry, val] of Object.entries(value)) {
@@ -2870,7 +2851,7 @@ class AnnotationStorage {
       }
     } else {
       modified = true;
-      this._storage.set(key, value);
+      this.#storage.set(key, value);
     }
     if (modified) {
       this.#setModified();
@@ -2880,25 +2861,25 @@ class AnnotationStorage {
     }
   }
   has(key) {
-    return this._storage.has(key);
+    return this.#storage.has(key);
   }
   getAll() {
-    return this._storage.size > 0 ? (0, _util.objectFromMap)(this._storage) : null;
+    return this.#storage.size > 0 ? (0, _util.objectFromMap)(this.#storage) : null;
   }
   get size() {
-    return this._storage.size;
+    return this.#storage.size;
   }
   #setModified() {
-    if (!this._modified) {
-      this._modified = true;
+    if (!this.#modified) {
+      this.#modified = true;
       if (typeof this.onSetModified === "function") {
         this.onSetModified();
       }
     }
   }
   resetModified() {
-    if (this._modified) {
-      this._modified = false;
+    if (this.#modified) {
+      this.#modified = false;
       if (typeof this.onResetModified === "function") {
         this.onResetModified();
       }
@@ -2908,11 +2889,11 @@ class AnnotationStorage {
     return new PrintAnnotationStorage(this);
   }
   get serializable() {
-    if (this._storage.size === 0) {
+    if (this.#storage.size === 0) {
       return null;
     }
     const clone = new Map();
-    for (const [key, val] of this._storage) {
+    for (const [key, val] of this.#storage) {
       const serialized = val instanceof _editor.AnnotationEditor ? val.serialize() : val;
       if (serialized) {
         clone.set(key, serialized);
@@ -4093,11 +4074,11 @@ function isDataScheme(url) {
 function isPdfFile(filename) {
   return typeof filename === "string" && /\.pdf$/i.test(filename);
 }
-function getFilenameFromUrl(url) {
-  const anchor = url.indexOf("#");
-  const query = url.indexOf("?");
-  const end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length);
-  return url.substring(url.lastIndexOf("/", end) + 1, end);
+function getFilenameFromUrl(url, onlyStripPath = false) {
+  if (!onlyStripPath) {
+    [url] = url.split(/[#?]/, 1);
+  }
+  return url.substring(url.lastIndexOf("/") + 1);
 }
 function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {
   if (typeof url !== "string") {
@@ -4122,10 +4103,8 @@ function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {
   return suggestedFilename || defaultFilename;
 }
 class StatTimer {
-  constructor() {
-    this.started = Object.create(null);
-    this.times = [];
-  }
+  started = Object.create(null);
+  times = [];
   time(name) {
     if (name in this.started) {
       (0, _util.warn)(`Timer is already running for ${name}`);
@@ -4146,15 +4125,17 @@ class StatTimer {
   toString() {
     const outBuf = [];
     let longest = 0;
-    for (const time of this.times) {
-      const name = time.name;
-      if (name.length > longest) {
-        longest = name.length;
-      }
+    for (const {
+      name
+    } of this.times) {
+      longest = Math.max(name.length, longest);
     }
-    for (const time of this.times) {
-      const duration = time.end - time.start;
-      outBuf.push(`${time.name.padEnd(longest)} ${duration}ms\n`);
+    for (const {
+      name,
+      start,
+      end
+    } of this.times) {
+      outBuf.push(`${name.padEnd(longest)} ${end - start}ms\n`);
     }
     return outBuf.join("");
   }
@@ -4533,9 +4514,7 @@ class MurmurHash3_64 {
     h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW;
     h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16;
     h1 ^= h2 >>> 1;
-    const hex1 = (h1 >>> 0).toString(16),
-      hex2 = (h2 >>> 0).toString(16);
-    return hex1.padStart(8, "0") + hex2.padStart(8, "0");
+    return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0");
   }
 }
 exports.MurmurHash3_64 = MurmurHash3_64;
@@ -5534,7 +5513,10 @@ const LINE_JOIN_STYLES = ["miter", "round", "bevel"];
 const NORMAL_CLIP = {};
 const EO_CLIP = {};
 class CanvasGraphics {
-  constructor(canvasCtx, commonObjs, objs, canvasFactory, optionalContentConfig, annotationCanvasMap, pageColors) {
+  constructor(canvasCtx, commonObjs, objs, canvasFactory, {
+    optionalContentConfig,
+    markedContentStack = null
+  }, annotationCanvasMap, pageColors) {
     this.ctx = canvasCtx;
     this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height);
     this.stateStack = [];
@@ -5555,7 +5537,7 @@ class CanvasGraphics {
     this.tempSMask = null;
     this.suspendedCtx = null;
     this.contentVisible = true;
-    this.markedContentStack = [];
+    this.markedContentStack = markedContentStack || [];
     this.optionalContentConfig = optionalContentConfig;
     this.cachedCanvases = new CachedCanvases(this.canvasFactory);
     this.cachedPatterns = new Map();
@@ -6355,6 +6337,19 @@ class CanvasGraphics {
       lineWidth /= fontSizeScale;
     }
     ctx.lineWidth = lineWidth;
+    if (font.isInvalidPDFjsFont) {
+      const chars = [];
+      let width = 0;
+      for (const glyph of glyphs) {
+        chars.push(glyph.unicode);
+        width += glyph.width;
+      }
+      ctx.fillText(chars.join(""), 0, 0);
+      current.x += width * widthAdvanceScale * textHScale;
+      ctx.restore();
+      this.compose();
+      return undefined;
+    }
     let x = 0,
       i;
     for (i = 0; i < glyphsLength; ++i) {
@@ -6490,7 +6485,10 @@ class CanvasGraphics {
       const baseTransform = this.baseTransform || (0, _display_utils.getCurrentTransform)(this.ctx);
       const canvasGraphicsFactory = {
         createCanvasGraphics: ctx => {
-          return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory);
+          return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory, {
+            optionalContentConfig: this.optionalContentConfig,
+            markedContentStack: this.markedContentStack
+          });
         }
       };
       pattern = new _pattern_helper.TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform);
@@ -6778,7 +6776,7 @@ class CanvasGraphics {
     const currentTransform = (0, _display_utils.getCurrentTransform)(ctx);
     ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0);
     const mask = this._createMaskCanvas(img);
-    ctx.setTransform(1, 0, 0, 1, 0, 0);
+    ctx.setTransform(1, 0, 0, 1, mask.offsetX - currentTransform[4], mask.offsetY - currentTransform[5]);
     for (let i = 0, ii = positions.length; i < ii; i += 2) {
       const trans = _util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]);
       const [x, y] = _util.Util.applyTransform([0, 0], trans);
@@ -9149,12 +9147,7 @@ class FreeTextEditor extends _editor.AnnotationEditor {
     }
     const buffer = [];
     for (const div of divs) {
-      const first = div.firstChild;
-      if (first?.nodeName === "#text") {
-        buffer.push(first.data);
-      } else {
-        buffer.push("");
-      }
+      buffer.push(div.innerText.replace(/\r\n?|\n/, ""));
     }
     return buffer.join("\n");
   }
@@ -10722,6 +10715,9 @@ class LinkAnnotationElement extends AnnotationElement {
     }
     return this.container;
   }
+  #setInternalLink() {
+    this.container.setAttribute("data-internal-link", "");
+  }
   _bindLink(link, destination) {
     link.href = this.linkService.getDestinationHash(destination);
     link.onclick = () => {
@@ -10731,7 +10727,7 @@ class LinkAnnotationElement extends AnnotationElement {
       return false;
     };
     if (destination || destination === "") {
-      link.className = "internalLink";
+      this.#setInternalLink();
     }
   }
   _bindNamedAction(link, action) {
@@ -10740,7 +10736,7 @@ class LinkAnnotationElement extends AnnotationElement {
       this.linkService.executeNamedAction(action);
       return false;
     };
-    link.className = "internalLink";
+    this.#setInternalLink();
   }
   _bindAttachment(link, attachment) {
     link.href = this.linkService.getAnchorUrl("");
@@ -10748,7 +10744,7 @@ class LinkAnnotationElement extends AnnotationElement {
       this.downloadManager?.openOrDownloadData(this.container, attachment.content, attachment.filename);
       return false;
     };
-    link.className = "internalLink";
+    this.#setInternalLink();
   }
   #bindSetOCGState(link, action) {
     link.href = this.linkService.getAnchorUrl("");
@@ -10756,7 +10752,7 @@ class LinkAnnotationElement extends AnnotationElement {
       this.linkService.executeSetOCGState(action);
       return false;
     };
-    link.className = "internalLink";
+    this.#setInternalLink();
   }
   _bindJSAction(link, data) {
     link.href = this.linkService.getAnchorUrl("");
@@ -10780,14 +10776,14 @@ class LinkAnnotationElement extends AnnotationElement {
     if (!link.onclick) {
       link.onclick = () => false;
     }
-    link.className = "internalLink";
+    this.#setInternalLink();
   }
   _bindResetFormAction(link, resetForm) {
     const otherClickAction = link.onclick;
     if (!otherClickAction) {
       link.href = this.linkService.getAnchorUrl("");
     }
-    link.className = "internalLink";
+    this.#setInternalLink();
     if (!this._fieldObjects) {
       (0, _util.warn)(`_bindResetFormAction - "resetForm" action not supported, ` + "ensure that the `fieldObjects` parameter is provided.");
       if (!otherClickAction) {
@@ -12133,7 +12129,7 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
       filename,
       content
     } = this.data.file;
-    this.filename = (0, _display_utils.getFilenameFromUrl)(filename);
+    this.filename = (0, _display_utils.getFilenameFromUrl)(filename, true);
     this.content = content;
     this.linkService.eventBus?.dispatch("fileattachmentannotation", {
       source: this,
@@ -12550,6 +12546,7 @@ Object.defineProperty(exports, "__esModule", ({
 exports.TextLayerRenderTask = void 0;
 exports.renderTextLayer = renderTextLayer;
 var _util = __w_pdfjs_require__(1);
+var _display_utils = __w_pdfjs_require__(6);
 const MAX_TEXT_DIVS_TO_RENDER = 100000;
 const DEFAULT_FONT_SIZE = 30;
 const DEFAULT_FONT_ASCENT = 0.8;
@@ -12708,7 +12705,6 @@ class TextLayerRenderTask {
     this._canceled = false;
     this._capability = (0, _util.createPromiseCapability)();
     this._renderTimer = null;
-    this._bounds = [];
     this._devicePixelRatio = globalThis.devicePixelRatio || 1;
     this._capability.promise.finally(() => {
       this._textDivProperties = null;
@@ -12829,6 +12825,7 @@ class TextLayerRenderTask {
       if (!timeout) {
         render(this);
       } else {
+        (0, _display_utils.deprecated)("The TextLayerRender `timeout` parameter will be removed in the " + "future, since streaming of textContent has made it obsolete.");
         this._renderTimer = setTimeout(() => {
           render(this);
           this._renderTimer = null;
@@ -15583,8 +15580,8 @@ var _is_node = __w_pdfjs_require__(12);
 var _text_layer = __w_pdfjs_require__(29);
 var _svg = __w_pdfjs_require__(30);
 var _xfa_layer = __w_pdfjs_require__(28);
-const pdfjsVersion = '3.0.279';
-const pdfjsBuild = 'd0823066c';
+const pdfjsVersion = '3.1.81';
+const pdfjsBuild = '0766898d5';
 {
   if (_is_node.isNodeJS) {
     const {

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
build/pdf.js.map


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
build/pdf.min.js


Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
build/pdf.sandbox.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
build/pdf.sandbox.js.map


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
build/pdf.sandbox.min.js


Разлика између датотеке није приказан због своје велике величине
+ 321 - 196
build/pdf.worker.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
build/pdf.worker.js.map


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
build/pdf.worker.min.js


+ 57 - 29
image_decoders/pdf.image_decoders.js

@@ -42,20 +42,18 @@ return /******/ (() => { // webpackBootstrap
 Object.defineProperty(exports, "__esModule", ({
   value: true
 }));
-exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMode = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;
+exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.BASELINE_FACTOR = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMode = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;
 exports.arrayByteLength = arrayByteLength;
 exports.arraysToBytes = arraysToBytes;
 exports.assert = assert;
 exports.bytesToString = bytesToString;
 exports.createPromiseCapability = createPromiseCapability;
 exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
-exports.escapeString = escapeString;
 exports.getModificationDate = getModificationDate;
 exports.getVerbosityLevel = getVerbosityLevel;
 exports.info = info;
 exports.isArrayBuffer = isArrayBuffer;
 exports.isArrayEqual = isArrayEqual;
-exports.isAscii = isAscii;
 exports.objectFromMap = objectFromMap;
 exports.objectSize = objectSize;
 exports.setVerbosityLevel = setVerbosityLevel;
@@ -63,7 +61,6 @@ exports.shadow = shadow;
 exports.string32 = string32;
 exports.stringToBytes = stringToBytes;
 exports.stringToPDFString = stringToPDFString;
-exports.stringToUTF16BEString = stringToUTF16BEString;
 exports.stringToUTF8String = stringToUTF8String;
 exports.unreachable = unreachable;
 exports.utf8StringToString = utf8StringToString;
@@ -77,10 +74,13 @@ const LINE_FACTOR = 1.35;
 exports.LINE_FACTOR = LINE_FACTOR;
 const LINE_DESCENT_FACTOR = 0.35;
 exports.LINE_DESCENT_FACTOR = LINE_DESCENT_FACTOR;
+const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR;
+exports.BASELINE_FACTOR = BASELINE_FACTOR;
 const RenderingIntentFlag = {
   ANY: 0x01,
   DISPLAY: 0x02,
   PRINT: 0x04,
+  SAVE: 0x08,
   ANNOTATIONS_FORMS: 0x10,
   ANNOTATIONS_STORAGE: 0x20,
   ANNOTATIONS_DISABLE: 0x40,
@@ -492,10 +492,10 @@ function createValidAbsoluteUrl(url, baseUrl = null, options = null) {
   } catch (ex) {}
   return null;
 }
-function shadow(obj, prop, value) {
+function shadow(obj, prop, value, nonSerializable = false) {
   Object.defineProperty(obj, prop, {
     value,
-    enumerable: true,
+    enumerable: !nonSerializable,
     configurable: true,
     writable: false
   });
@@ -858,27 +858,6 @@ function stringToPDFString(str) {
   }
   return strBuf.join("");
 }
-function escapeString(str) {
-  return str.replace(/([()\\\n\r])/g, match => {
-    if (match === "\n") {
-      return "\\n";
-    } else if (match === "\r") {
-      return "\\r";
-    }
-    return `\\${match}`;
-  });
-}
-function isAscii(str) {
-  return /^[\x00-\x7F]*$/.test(str);
-}
-function stringToUTF16BEString(str) {
-  const buf = ["\xFE\xFF"];
-  for (let i = 0, ii = str.length; i < ii; i++) {
-    const char = str.charCodeAt(i);
-    buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff));
-  }
-  return buf.join("");
-}
 function stringToUTF8String(str) {
   return decodeURIComponent(escape(str));
 }
@@ -2729,10 +2708,13 @@ exports.XRefParseException = exports.XRefEntryException = exports.ParserEOFExcep
 exports.collectActions = collectActions;
 exports.encodeToXmlString = encodeToXmlString;
 exports.escapePDFName = escapePDFName;
+exports.escapeString = escapeString;
 exports.getArrayLookupTableFactory = getArrayLookupTableFactory;
 exports.getInheritableProperty = getInheritableProperty;
 exports.getLookupTableFactory = getLookupTableFactory;
 exports.getNewAnnotationsMap = getNewAnnotationsMap;
+exports.getRotationMatrix = getRotationMatrix;
+exports.isAscii = isAscii;
 exports.isWhiteSpace = isWhiteSpace;
 exports.log2 = log2;
 exports.numberToString = numberToString;
@@ -2741,6 +2723,8 @@ exports.readInt8 = readInt8;
 exports.readUint16 = readUint16;
 exports.readUint32 = readUint32;
 exports.recoverJsURL = recoverJsURL;
+exports.stringToUTF16HexString = stringToUTF16HexString;
+exports.stringToUTF16String = stringToUTF16String;
 exports.toRomanNumerals = toRomanNumerals;
 exports.validateCSSFont = validateCSSFont;
 var _util = __w_pdfjs_require__(1);
@@ -2936,6 +2920,16 @@ function escapePDFName(str) {
   }
   return buffer.join("");
 }
+function escapeString(str) {
+  return str.replace(/([()\\\n\r])/g, match => {
+    if (match === "\n") {
+      return "\\n";
+    } else if (match === "\r") {
+      return "\\r";
+    }
+    return `\\${match}`;
+  });
+}
 function _collectJS(entry, xref, list, parents) {
   if (!entry) {
     return;
@@ -3133,6 +3127,40 @@ function getNewAnnotationsMap(annotationStorage) {
   }
   return newAnnotationsByPage.size > 0 ? newAnnotationsByPage : null;
 }
+function isAscii(str) {
+  return /^[\x00-\x7F]*$/.test(str);
+}
+function stringToUTF16HexString(str) {
+  const buf = [];
+  for (let i = 0, ii = str.length; i < ii; i++) {
+    const char = str.charCodeAt(i);
+    buf.push((char >> 8 & 0xff).toString(16).padStart(2, "0"), (char & 0xff).toString(16).padStart(2, "0"));
+  }
+  return buf.join("");
+}
+function stringToUTF16String(str, bigEndian = false) {
+  const buf = [];
+  if (bigEndian) {
+    buf.push("\xFE\xFF");
+  }
+  for (let i = 0, ii = str.length; i < ii; i++) {
+    const char = str.charCodeAt(i);
+    buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff));
+  }
+  return buf.join("");
+}
+function getRotationMatrix(rotation, width, height) {
+  switch (rotation) {
+    case 90:
+      return [0, 1, -1, 0, width, 0];
+    case 180:
+      return [-1, 0, 0, -1, width, height];
+    case 270:
+      return [0, -1, 1, 0, 0, height];
+    default:
+      throw new Error("Invalid rotation");
+  }
+}
 
 /***/ }),
 /* 4 */
@@ -7391,8 +7419,8 @@ var _util = __w_pdfjs_require__(1);
 var _jbig = __w_pdfjs_require__(2);
 var _jpg = __w_pdfjs_require__(8);
 var _jpx = __w_pdfjs_require__(9);
-const pdfjsVersion = '3.0.279';
-const pdfjsBuild = 'd0823066c';
+const pdfjsVersion = '3.1.81';
+const pdfjsBuild = '0766898d5';
 })();
 
 /******/ 	return __webpack_exports__;

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
image_decoders/pdf.image_decoders.js.map


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
image_decoders/pdf.image_decoders.min.js


Разлика између датотеке није приказан због своје велике величине
+ 195 - 226
legacy/build/pdf.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
legacy/build/pdf.js.map


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
legacy/build/pdf.min.js


Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
legacy/build/pdf.sandbox.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
legacy/build/pdf.sandbox.js.map


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
legacy/build/pdf.sandbox.min.js


Разлика између датотеке није приказан због своје велике величине
+ 190 - 219
legacy/build/pdf.worker.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
legacy/build/pdf.worker.js.map


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
legacy/build/pdf.worker.min.js


Разлика између датотеке није приказан због своје велике величине
+ 194 - 225
legacy/image_decoders/pdf.image_decoders.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
legacy/image_decoders/pdf.image_decoders.js.map


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
legacy/image_decoders/pdf.image_decoders.min.js


Разлика између датотеке није приказан због своје велике величине
+ 949 - 889
legacy/web/pdf_viewer.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
legacy/web/pdf_viewer.js.map


Разлика између датотеке није приказан због своје велике величине
+ 338 - 219
lib/core/annotation.js


+ 7 - 0
lib/core/catalog.js

@@ -977,6 +977,9 @@ class Catalog {
     throw new Error(`Page index ${pageIndex} not found.`);
   }
   async getAllPageDicts(recoveryMode = false) {
+    const {
+      ignoreErrors
+    } = this.pdfManager.evaluatorOptions;
     const queue = [{
       currentNode: this.toplevelPagesDict,
       posInKids: 0
@@ -1000,6 +1003,10 @@ class Catalog {
       if (error instanceof _core_utils.XRefEntryException && !recoveryMode) {
         throw error;
       }
+      if (recoveryMode && ignoreErrors && pageIndex === 0) {
+        (0, _util.warn)(`getAllPageDicts - Skipping invalid first page: "${error}".`);
+        error = _primitives.Dict.empty;
+      }
       map.set(pageIndex++, [error, null]);
     }
     while (queue.length > 0) {

+ 49 - 0
lib/core/core_utils.js

@@ -28,10 +28,13 @@ exports.XRefParseException = exports.XRefEntryException = exports.ParserEOFExcep
 exports.collectActions = collectActions;
 exports.encodeToXmlString = encodeToXmlString;
 exports.escapePDFName = escapePDFName;
+exports.escapeString = escapeString;
 exports.getArrayLookupTableFactory = getArrayLookupTableFactory;
 exports.getInheritableProperty = getInheritableProperty;
 exports.getLookupTableFactory = getLookupTableFactory;
 exports.getNewAnnotationsMap = getNewAnnotationsMap;
+exports.getRotationMatrix = getRotationMatrix;
+exports.isAscii = isAscii;
 exports.isWhiteSpace = isWhiteSpace;
 exports.log2 = log2;
 exports.numberToString = numberToString;
@@ -40,6 +43,8 @@ exports.readInt8 = readInt8;
 exports.readUint16 = readUint16;
 exports.readUint32 = readUint32;
 exports.recoverJsURL = recoverJsURL;
+exports.stringToUTF16HexString = stringToUTF16HexString;
+exports.stringToUTF16String = stringToUTF16String;
 exports.toRomanNumerals = toRomanNumerals;
 exports.validateCSSFont = validateCSSFont;
 var _util = require("../shared/util.js");
@@ -235,6 +240,16 @@ function escapePDFName(str) {
   }
   return buffer.join("");
 }
+function escapeString(str) {
+  return str.replace(/([()\\\n\r])/g, match => {
+    if (match === "\n") {
+      return "\\n";
+    } else if (match === "\r") {
+      return "\\r";
+    }
+    return `\\${match}`;
+  });
+}
 function _collectJS(entry, xref, list, parents) {
   if (!entry) {
     return;
@@ -431,4 +446,38 @@ function getNewAnnotationsMap(annotationStorage) {
     annotations.push(value);
   }
   return newAnnotationsByPage.size > 0 ? newAnnotationsByPage : null;
+}
+function isAscii(str) {
+  return /^[\x00-\x7F]*$/.test(str);
+}
+function stringToUTF16HexString(str) {
+  const buf = [];
+  for (let i = 0, ii = str.length; i < ii; i++) {
+    const char = str.charCodeAt(i);
+    buf.push((char >> 8 & 0xff).toString(16).padStart(2, "0"), (char & 0xff).toString(16).padStart(2, "0"));
+  }
+  return buf.join("");
+}
+function stringToUTF16String(str, bigEndian = false) {
+  const buf = [];
+  if (bigEndian) {
+    buf.push("\xFE\xFF");
+  }
+  for (let i = 0, ii = str.length; i < ii; i++) {
+    const char = str.charCodeAt(i);
+    buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff));
+  }
+  return buf.join("");
+}
+function getRotationMatrix(rotation, width, height) {
+  switch (rotation) {
+    case 90:
+      return [0, 1, -1, 0, width, 0];
+    case 180:
+      return [-1, 0, 0, -1, width, height];
+    case 270:
+      return [0, -1, 1, 0, 0, height];
+    default:
+      throw new Error("Invalid rotation");
+  }
 }

+ 197 - 2
lib/core/default_appearance.js

@@ -24,14 +24,15 @@
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
+exports.FakeUnicodeFont = void 0;
 exports.createDefaultAppearance = createDefaultAppearance;
 exports.getPdfColor = getPdfColor;
 exports.parseDefaultAppearance = parseDefaultAppearance;
+var _primitives = require("./primitives.js");
 var _core_utils = require("./core_utils.js");
 var _util = require("../shared/util.js");
 var _colorspace = require("./colorspace.js");
 var _evaluator = require("./evaluator.js");
-var _primitives = require("./primitives.js");
 var _stream = require("./stream.js");
 class DefaultAppearanceEvaluator extends _evaluator.EvaluatorPreprocessor {
   constructor(str) {
@@ -103,4 +104,198 @@ function createDefaultAppearance({
   fontColor
 }) {
   return `/${(0, _core_utils.escapePDFName)(fontName)} ${fontSize} Tf ${getPdfColor(fontColor, true)}`;
-}
+}
+class FakeUnicodeFont {
+  constructor(xref, fontFamily) {
+    this.xref = xref;
+    this.widths = null;
+    this.firstChar = Infinity;
+    this.lastChar = -Infinity;
+    this.fontFamily = fontFamily;
+    const canvas = new OffscreenCanvas(1, 1);
+    this.ctxMeasure = canvas.getContext("2d");
+    if (!FakeUnicodeFont._fontNameId) {
+      FakeUnicodeFont._fontNameId = 1;
+    }
+    this.fontName = _primitives.Name.get(`InvalidPDFjsFont_${fontFamily}_${FakeUnicodeFont._fontNameId++}`);
+  }
+  get toUnicodeRef() {
+    if (!FakeUnicodeFont._toUnicodeRef) {
+      const toUnicode = `/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (Adobe)
+/Ordering (UCS) /Supplement 0 >> def
+/CMapName /Adobe-Identity-UCS def
+/CMapType 2 def
+1 begincodespacerange
+<0000> <FFFF>
+endcodespacerange
+1 beginbfrange
+<0000> <FFFF> <0000>
+endbfrange
+endcmap CMapName currentdict /CMap defineresource pop end end`;
+      const toUnicodeStream = FakeUnicodeFont.toUnicodeStream = new _stream.StringStream(toUnicode);
+      const toUnicodeDict = new _primitives.Dict(this.xref);
+      toUnicodeStream.dict = toUnicodeDict;
+      toUnicodeDict.set("Length", toUnicode.length);
+      FakeUnicodeFont._toUnicodeRef = this.xref.getNewPersistentRef(toUnicodeStream);
+    }
+    return FakeUnicodeFont._toUnicodeRef;
+  }
+  get fontDescriptorRef() {
+    if (!FakeUnicodeFont._fontDescriptorRef) {
+      const fontDescriptor = new _primitives.Dict(this.xref);
+      fontDescriptor.set("Type", _primitives.Name.get("FontDescriptor"));
+      fontDescriptor.set("FontName", this.fontName);
+      fontDescriptor.set("FontFamily", "MyriadPro Regular");
+      fontDescriptor.set("FontBBox", [0, 0, 0, 0]);
+      fontDescriptor.set("FontStretch", _primitives.Name.get("Normal"));
+      fontDescriptor.set("FontWeight", 400);
+      fontDescriptor.set("ItalicAngle", 0);
+      FakeUnicodeFont._fontDescriptorRef = this.xref.getNewPersistentRef(fontDescriptor);
+    }
+    return FakeUnicodeFont._fontDescriptorRef;
+  }
+  get descendantFontRef() {
+    const descendantFont = new _primitives.Dict(this.xref);
+    descendantFont.set("BaseFont", this.fontName);
+    descendantFont.set("Type", _primitives.Name.get("Font"));
+    descendantFont.set("Subtype", _primitives.Name.get("CIDFontType0"));
+    descendantFont.set("CIDToGIDMap", _primitives.Name.get("Identity"));
+    descendantFont.set("FirstChar", this.firstChar);
+    descendantFont.set("LastChar", this.lastChar);
+    descendantFont.set("FontDescriptor", this.fontDescriptorRef);
+    descendantFont.set("DW", 1000);
+    const widths = [];
+    const chars = [...this.widths.entries()].sort();
+    let currentChar = null;
+    let currentWidths = null;
+    for (const [char, width] of chars) {
+      if (!currentChar) {
+        currentChar = char;
+        currentWidths = [width];
+        continue;
+      }
+      if (char === currentChar + currentWidths.length) {
+        currentWidths.push(width);
+      } else {
+        widths.push(currentChar, currentWidths);
+        currentChar = char;
+        currentWidths = [width];
+      }
+    }
+    if (currentChar) {
+      widths.push(currentChar, currentWidths);
+    }
+    descendantFont.set("W", widths);
+    const cidSystemInfo = new _primitives.Dict(this.xref);
+    cidSystemInfo.set("Ordering", "Identity");
+    cidSystemInfo.set("Registry", "Adobe");
+    cidSystemInfo.set("Supplement", 0);
+    descendantFont.set("CIDSystemInfo", cidSystemInfo);
+    return this.xref.getNewPersistentRef(descendantFont);
+  }
+  get baseFontRef() {
+    const baseFont = new _primitives.Dict(this.xref);
+    baseFont.set("BaseFont", this.fontName);
+    baseFont.set("Type", _primitives.Name.get("Font"));
+    baseFont.set("Subtype", _primitives.Name.get("Type0"));
+    baseFont.set("Encoding", _primitives.Name.get("Identity-H"));
+    baseFont.set("DescendantFonts", [this.descendantFontRef]);
+    baseFont.set("ToUnicode", this.toUnicodeRef);
+    return this.xref.getNewPersistentRef(baseFont);
+  }
+  get resources() {
+    const resources = new _primitives.Dict(this.xref);
+    const font = new _primitives.Dict(this.xref);
+    font.set(this.fontName.name, this.baseFontRef);
+    resources.set("Font", font);
+    return resources;
+  }
+  _createContext() {
+    this.widths = new Map();
+    this.ctxMeasure.font = `1000px ${this.fontFamily}`;
+    return this.ctxMeasure;
+  }
+  createFontResources(text) {
+    const ctx = this._createContext();
+    for (const line of text.split(/\r\n?|\n/)) {
+      for (const char of line.split("")) {
+        const code = char.charCodeAt(0);
+        if (this.widths.has(code)) {
+          continue;
+        }
+        const metrics = ctx.measureText(char);
+        const width = Math.ceil(metrics.width);
+        this.widths.set(code, width);
+        this.firstChar = Math.min(code, this.firstChar);
+        this.lastChar = Math.max(code, this.lastChar);
+      }
+    }
+    return this.resources;
+  }
+  createAppearance(text, rect, rotation, fontSize, bgColor) {
+    const ctx = this._createContext();
+    const lines = [];
+    let maxWidth = -Infinity;
+    for (const line of text.split(/\r\n?|\n/)) {
+      lines.push(line);
+      const lineWidth = ctx.measureText(line).width;
+      maxWidth = Math.max(maxWidth, lineWidth);
+      for (const char of line.split("")) {
+        const code = char.charCodeAt(0);
+        let width = this.widths.get(code);
+        if (width === undefined) {
+          const metrics = ctx.measureText(char);
+          width = Math.ceil(metrics.width);
+          this.widths.set(code, width);
+          this.firstChar = Math.min(code, this.firstChar);
+          this.lastChar = Math.max(code, this.lastChar);
+        }
+      }
+    }
+    maxWidth *= fontSize / 1000;
+    const [x1, y1, x2, y2] = rect;
+    let w = x2 - x1;
+    let h = y2 - y1;
+    if (rotation % 180 !== 0) {
+      [w, h] = [h, w];
+    }
+    let hscale = 1;
+    if (maxWidth > w) {
+      hscale = w / maxWidth;
+    }
+    let vscale = 1;
+    const lineHeight = _util.LINE_FACTOR * fontSize;
+    const lineDescent = _util.LINE_DESCENT_FACTOR * fontSize;
+    const maxHeight = lineHeight * lines.length;
+    if (maxHeight > h) {
+      vscale = h / maxHeight;
+    }
+    const fscale = Math.min(hscale, vscale);
+    const newFontSize = fontSize * fscale;
+    const buffer = ["q", `0 0 ${(0, _core_utils.numberToString)(w)} ${(0, _core_utils.numberToString)(h)} re W n`, `BT`, `1 0 0 1 0 ${(0, _core_utils.numberToString)(h + lineDescent)} Tm 0 Tc ${getPdfColor(bgColor, true)}`, `/${this.fontName.name} ${(0, _core_utils.numberToString)(newFontSize)} Tf`];
+    const vShift = (0, _core_utils.numberToString)(lineHeight);
+    for (const line of lines) {
+      buffer.push(`0 -${vShift} Td <${(0, _core_utils.stringToUTF16HexString)(line)}> Tj`);
+    }
+    buffer.push("ET", "Q");
+    const appearance = buffer.join("\n");
+    const appearanceStreamDict = new _primitives.Dict(this.xref);
+    appearanceStreamDict.set("Subtype", _primitives.Name.get("Form"));
+    appearanceStreamDict.set("Type", _primitives.Name.get("XObject"));
+    appearanceStreamDict.set("BBox", [0, 0, w, h]);
+    appearanceStreamDict.set("Length", appearance.length);
+    appearanceStreamDict.set("Resources", this.resources);
+    if (rotation) {
+      const matrix = (0, _core_utils.getRotationMatrix)(rotation, w, h);
+      appearanceStreamDict.set("Matrix", matrix);
+    }
+    const ap = new _stream.StringStream(appearance);
+    ap.dict = appearanceStreamDict;
+    return ap;
+  }
+}
+exports.FakeUnicodeFont = FakeUnicodeFont;

+ 15 - 11
lib/core/evaluator.js

@@ -32,7 +32,6 @@ var _fonts = require("./fonts.js");
 var _fonts_utils = require("./fonts_utils.js");
 var _encodings = require("./encodings.js");
 var _standard_fonts = require("./standard_fonts.js");
-var _unicode = require("./unicode.js");
 var _pattern = require("./pattern.js");
 var _xfa_fonts = require("./xfa_fonts.js");
 var _to_unicode_map = require("./to_unicode_map.js");
@@ -47,6 +46,7 @@ var _decode_stream = require("./decode_stream.js");
 var _glyphlist = require("./glyphlist.js");
 var _core_utils = require("./core_utils.js");
 var _metrics = require("./metrics.js");
+var _unicode = require("./unicode.js");
 var _murmurhash = require("../shared/murmurhash3.js");
 var _operator_list = require("./operator_list.js");
 var _image = require("./image.js");
@@ -1635,7 +1635,6 @@ class PartialEvaluator {
         level: 0
       };
     }
-    const NormalizedUnicodes = (0, _unicode.getNormalizedUnicodes)();
     const textContent = {
       items: [],
       styles: Object.create(null)
@@ -1700,8 +1699,10 @@ class PartialEvaluator {
       if (textContentItem.initialized) {
         return textContentItem;
       }
-      const font = textState.font,
-        loadedName = font.loadedName;
+      const {
+        font,
+        loadedName
+      } = textState;
       if (!seenStyles.has(loadedName)) {
         seenStyles.add(loadedName);
         textContent.styles[loadedName] = {
@@ -1775,6 +1776,7 @@ class PartialEvaluator {
           return translated;
         });
       }).then(function (translated) {
+        textState.loadedName = translated.loadedName;
         textState.font = translated.font;
         textState.fontMatrix = translated.font.fontMatrix || _util.FONT_IDENTITY_MATRIX;
       });
@@ -1923,7 +1925,10 @@ class PartialEvaluator {
       const scale = textState.fontMatrix[0] * textState.fontSize;
       for (let i = 0, ii = glyphs.length; i < ii; i++) {
         const glyph = glyphs[i];
-        if (glyph.isInvisibleFormatMark) {
+        const {
+          category
+        } = glyph;
+        if (category.isInvisibleFormatMark) {
           continue;
         }
         let charSpacing = textState.charSpacing + (i + 1 === ii ? extraSpacing : 0);
@@ -1932,7 +1937,7 @@ class PartialEvaluator {
           glyphWidth = glyph.vmetric ? glyph.vmetric[0] : -glyphWidth;
         }
         let scaledDim = glyphWidth * scale;
-        if (glyph.isWhitespace) {
+        if (category.isWhitespace) {
           if (!font.vertical) {
             charSpacing += scaledDim + textState.wordSpacing;
             textState.translateTextMatrix(charSpacing * textState.textHScale, 0);
@@ -1947,7 +1952,7 @@ class PartialEvaluator {
           continue;
         }
         const textChunk = ensureTextContentItem();
-        if (glyph.isZeroWidthDiacritic) {
+        if (category.isZeroWidthDiacritic) {
           scaledDim = 0;
         }
         if (!font.vertical) {
@@ -1962,9 +1967,7 @@ class PartialEvaluator {
         if (scaledDim) {
           textChunk.prevTransform = getCurrentTextTransform();
         }
-        let glyphUnicode = glyph.unicode;
-        glyphUnicode = NormalizedUnicodes[glyphUnicode] || glyphUnicode;
-        glyphUnicode = (0, _unicode.reverseIfRtl)(glyphUnicode);
+        const glyphUnicode = glyph.normalizedUnicode;
         if (saveLastChar(glyphUnicode)) {
           textChunk.str.push(" ");
         }
@@ -1990,7 +1993,7 @@ class PartialEvaluator {
           width: 0,
           height: 0,
           transform: getCurrentTextTransform(),
-          fontName: textState.font.loadedName,
+          fontName: textState.loadedName,
           hasEOL: true
         });
       }
@@ -3295,6 +3298,7 @@ class TextState {
     this.ctm = new Float32Array(_util.IDENTITY_MATRIX);
     this.fontName = null;
     this.fontSize = 0;
+    this.loadedName = null;
     this.font = null;
     this.fontMatrix = _util.FONT_IDENTITY_MATRIX;
     this.textMatrix = _util.IDENTITY_MATRIX.slice();

+ 20 - 11
lib/core/fonts.js

@@ -44,7 +44,7 @@ var _stream = require("./stream.js");
 var _type1_font = require("./type1_font.js");
 const PRIVATE_USE_AREAS = [[0xe000, 0xf8ff], [0x100000, 0x10fffd]];
 const PDF_GLYPH_SPACE_UNITS = 1000;
-const EXPORT_DATA_PROPERTIES = ["ascent", "bbox", "black", "bold", "charProcOperatorList", "composite", "cssFontInfo", "data", "defaultVMetrics", "defaultWidth", "descent", "fallbackName", "fontMatrix", "fontType", "isType3Font", "italic", "loadedName", "mimetype", "missingFile", "name", "remeasure", "subtype", "type", "vertical"];
+const EXPORT_DATA_PROPERTIES = ["ascent", "bbox", "black", "bold", "charProcOperatorList", "composite", "cssFontInfo", "data", "defaultVMetrics", "defaultWidth", "descent", "fallbackName", "fontMatrix", "fontType", "isInvalidPDFjsFont", "isType3Font", "italic", "loadedName", "mimetype", "missingFile", "name", "remeasure", "subtype", "type", "vertical"];
 const EXPORT_DATA_EXTRA_PROPERTIES = ["cMap", "defaultEncoding", "differences", "isMonospace", "isSerifFont", "isSymbolicFont", "seacMap", "toFontChar", "toUnicode", "vmetrics", "widths"];
 function adjustWidths(properties) {
   if (!properties.fontMatrix) {
@@ -120,10 +120,15 @@ class Glyph {
     this.operatorListId = operatorListId;
     this.isSpace = isSpace;
     this.isInFont = isInFont;
-    const category = (0, _unicode.getCharUnicodeCategory)(unicode);
-    this.isWhitespace = category.isWhitespace;
-    this.isZeroWidthDiacritic = category.isZeroWidthDiacritic;
-    this.isInvisibleFormatMark = category.isInvisibleFormatMark;
+  }
+  get category() {
+    return (0, _util.shadow)(this, "category", (0, _unicode.getCharUnicodeCategory)(this.unicode), true);
+  }
+  get normalizedUnicode() {
+    return (0, _util.shadow)(this, "normalizedUnicode", (0, _unicode.reverseIfRtl)(Glyph._NormalizedUnicodes[this.unicode] || this.unicode), true);
+  }
+  static get _NormalizedUnicodes() {
+    return (0, _util.shadow)(this, "_NormalizedUnicodes", (0, _unicode.getNormalizedUnicodes)());
   }
 }
 function int16(b0, b1) {
@@ -581,13 +586,17 @@ class Font {
     let subtype = properties.subtype;
     this.type = type;
     this.subtype = subtype;
-    let fallbackName = "sans-serif";
-    if (this.isMonospace) {
-      fallbackName = "monospace";
+    const matches = name.match(/^InvalidPDFjsFont_(.*)_\d+$/);
+    this.isInvalidPDFjsFont = !!matches;
+    if (this.isInvalidPDFjsFont) {
+      this.fallbackName = matches[1];
+    } else if (this.isMonospace) {
+      this.fallbackName = "monospace";
     } else if (this.isSerifFont) {
-      fallbackName = "serif";
+      this.fallbackName = "serif";
+    } else {
+      this.fallbackName = "sans-serif";
     }
-    this.fallbackName = fallbackName;
     this.differences = properties.differences;
     this.widths = properties.widths;
     this.defaultWidth = properties.defaultWidth;
@@ -771,7 +780,7 @@ class Font {
         map[+charCode] = unicodeCharCode;
       });
       if (this.composite && this.toUnicode instanceof _to_unicode_map.IdentityToUnicodeMap) {
-        if (/Verdana/i.test(name)) {
+        if (/Tahoma|Verdana/i.test(name)) {
           applyStandardFontGlyphMap(map, (0, _standard_fonts.getGlyphMapForStandardFonts)());
         }
       }

+ 22 - 20
lib/core/parser.js

@@ -40,16 +40,17 @@ var _stream = require("./stream.js");
 var _predictor_stream = require("./predictor_stream.js");
 var _run_length_stream = require("./run_length_stream.js");
 const MAX_LENGTH_TO_CACHE = 1000;
-const MAX_ADLER32_LENGTH = 5552;
-function computeAdler32(bytes) {
-  const bytesLength = bytes.length;
-  let a = 1,
-    b = 0;
-  for (let i = 0; i < bytesLength; ++i) {
-    a += bytes[i] & 0xff;
-    b += a;
+function getInlineImageCacheKey(bytes) {
+  const strBuf = [],
+    ii = bytes.length;
+  let i = 0;
+  while (i < ii - 1) {
+    strBuf.push(bytes[i++] << 8 | bytes[i++]);
   }
-  return b % 65521 << 16 | a % 65521;
+  if (i < ii) {
+    strBuf.push(bytes[i]);
+  }
+  return ii + "_" + String.fromCharCode.apply(null, strBuf);
 }
 class Parser {
   constructor({
@@ -63,6 +64,7 @@ class Parser {
     this.allowStreams = allowStreams;
     this.recoveryMode = recoveryMode;
     this.imageCache = Object.create(null);
+    this._imageId = 0;
     this.refill();
   }
   refill() {
@@ -175,7 +177,6 @@ class Parser {
       } else if (state === 1) {
         state = ch === I ? 2 : 0;
       } else {
-        (0, _util.assert)(state === 2, "findDefaultInlineStreamEnd - invalid state.");
         if (ch === SPACE || ch === LF || ch === CR) {
           maybeEIPos = stream.pos;
           const followingBytes = stream.peekBytes(n);
@@ -371,7 +372,7 @@ class Parser {
   makeInlineImage(cipherTransform) {
     const lexer = this.lexer;
     const stream = lexer.stream;
-    const dict = new _primitives.Dict(this.xref);
+    const dictMap = Object.create(null);
     let dictLength;
     while (!(0, _primitives.isCmd)(this.buf1, "ID") && this.buf1 !== _primitives.EOF) {
       if (!(this.buf1 instanceof _primitives.Name)) {
@@ -382,12 +383,12 @@ class Parser {
       if (this.buf1 === _primitives.EOF) {
         break;
       }
-      dict.set(key, this.getObj(cipherTransform));
+      dictMap[key] = this.getObj(cipherTransform);
     }
     if (lexer.beginInlineImagePos !== -1) {
       dictLength = stream.pos - lexer.beginInlineImagePos;
     }
-    const filter = dict.get("F", "Filter");
+    const filter = this.xref.fetchIfRef(dictMap.F || dictMap.Filter);
     let filterName;
     if (filter instanceof _primitives.Name) {
       filterName = filter.name;
@@ -415,16 +416,12 @@ class Parser {
       default:
         length = this.findDefaultInlineStreamEnd(stream);
     }
-    let imageStream = stream.makeSubStream(startPos, length, dict);
     let cacheKey;
-    if (length < MAX_LENGTH_TO_CACHE && dictLength < MAX_ADLER32_LENGTH) {
-      const imageBytes = imageStream.getBytes();
-      imageStream.reset();
+    if (length < MAX_LENGTH_TO_CACHE && dictLength > 0) {
       const initialStreamPos = stream.pos;
       stream.pos = lexer.beginInlineImagePos;
-      const dictBytes = stream.getBytes(dictLength);
+      cacheKey = getInlineImageCacheKey(stream.getBytes(dictLength + length));
       stream.pos = initialStreamPos;
-      cacheKey = computeAdler32(imageBytes) + "_" + computeAdler32(dictBytes);
       const cacheEntry = this.imageCache[cacheKey];
       if (cacheEntry !== undefined) {
         this.buf2 = _primitives.Cmd.get("EI");
@@ -433,13 +430,18 @@ class Parser {
         return cacheEntry;
       }
     }
+    const dict = new _primitives.Dict(this.xref);
+    for (const key in dictMap) {
+      dict.set(key, dictMap[key]);
+    }
+    let imageStream = stream.makeSubStream(startPos, length, dict);
     if (cipherTransform) {
       imageStream = cipherTransform.createStream(imageStream, length);
     }
     imageStream = this.filter(imageStream, dict, length);
     imageStream.dict = dict;
     if (cacheKey !== undefined) {
-      imageStream.cacheKey = `inline_${length}_${cacheKey}`;
+      imageStream.cacheKey = `inline_img_${++this._imageId}`;
       this.imageCache[cacheKey] = imageStream;
     }
     this.buf2 = _primitives.Cmd.get("EI");

+ 46 - 44
lib/core/worker.js

@@ -59,17 +59,17 @@ exports.WorkerTask = WorkerTask;
 class WorkerMessageHandler {
   static setup(handler, port) {
     let testMessageProcessed = false;
-    handler.on("test", function wphSetupTest(data) {
+    handler.on("test", function (data) {
       if (testMessageProcessed) {
         return;
       }
       testMessageProcessed = true;
       handler.send("test", data instanceof Uint8Array);
     });
-    handler.on("configure", function wphConfigure(data) {
+    handler.on("configure", function (data) {
       (0, _util.setVerbosityLevel)(data.verbosity);
     });
-    handler.on("GetDocRequest", function wphSetupDoc(data) {
+    handler.on("GetDocRequest", function (data) {
       return WorkerMessageHandler.createDocumentHandler(data, port);
     });
   }
@@ -83,7 +83,7 @@ class WorkerMessageHandler {
       docId,
       apiVersion
     } = docParams;
-    const workerVersion = '3.0.279';
+    const workerVersion = '3.1.81';
     if (apiVersion !== workerVersion) {
       throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
     }
@@ -202,7 +202,7 @@ class WorkerMessageHandler {
         }
         cachedChunks = [];
       };
-      const readPromise = new Promise(function (resolve, reject) {
+      new Promise(function (resolve, reject) {
         const readChunk = function ({
           value,
           done
@@ -234,8 +234,7 @@ class WorkerMessageHandler {
           }
         };
         fullRequest.read().then(readChunk, reject);
-      });
-      readPromise.catch(function (e) {
+      }).catch(function (e) {
         pdfManagerCapability.reject(e);
         cancelXHRs = null;
       });
@@ -300,7 +299,7 @@ class WorkerMessageHandler {
         });
       }).then(pdfManagerReady, onFailure);
     }
-    handler.on("GetPage", function wphSetupGetPage(data) {
+    handler.on("GetPage", function (data) {
       return pdfManager.getPage(data.pageIndex).then(function (page) {
         return Promise.all([pdfManager.ensure(page, "rotate"), pdfManager.ensure(page, "ref"), pdfManager.ensure(page, "userUnit"), pdfManager.ensure(page, "view")]).then(function ([rotate, ref, userUnit, view]) {
           return {
@@ -312,23 +311,23 @@ class WorkerMessageHandler {
         });
       });
     });
-    handler.on("GetPageIndex", function wphSetupGetPageIndex(data) {
+    handler.on("GetPageIndex", function (data) {
       const pageRef = _primitives.Ref.get(data.num, data.gen);
       return pdfManager.ensureCatalog("getPageIndex", [pageRef]);
     });
-    handler.on("GetDestinations", function wphSetupGetDestinations(data) {
+    handler.on("GetDestinations", function (data) {
       return pdfManager.ensureCatalog("destinations");
     });
-    handler.on("GetDestination", function wphSetupGetDestination(data) {
+    handler.on("GetDestination", function (data) {
       return pdfManager.ensureCatalog("getDestination", [data.id]);
     });
-    handler.on("GetPageLabels", function wphSetupGetPageLabels(data) {
+    handler.on("GetPageLabels", function (data) {
       return pdfManager.ensureCatalog("pageLabels");
     });
-    handler.on("GetPageLayout", function wphSetupGetPageLayout(data) {
+    handler.on("GetPageLayout", function (data) {
       return pdfManager.ensureCatalog("pageLayout");
     });
-    handler.on("GetPageMode", function wphSetupGetPageMode(data) {
+    handler.on("GetPageMode", function (data) {
       return pdfManager.ensureCatalog("pageMode");
     });
     handler.on("GetViewerPreferences", function (data) {
@@ -337,13 +336,13 @@ class WorkerMessageHandler {
     handler.on("GetOpenAction", function (data) {
       return pdfManager.ensureCatalog("openAction");
     });
-    handler.on("GetAttachments", function wphSetupGetAttachments(data) {
+    handler.on("GetAttachments", function (data) {
       return pdfManager.ensureCatalog("attachments");
     });
-    handler.on("GetJavaScript", function wphSetupGetJavaScript(data) {
+    handler.on("GetJavaScript", function (data) {
       return pdfManager.ensureCatalog("javaScript");
     });
-    handler.on("GetDocJSActions", function wphSetupGetDocJSActions(data) {
+    handler.on("GetDocJSActions", function (data) {
       return pdfManager.ensureCatalog("jsActions");
     });
     handler.on("GetPageJSActions", function ({
@@ -353,7 +352,7 @@ class WorkerMessageHandler {
         return pdfManager.ensure(page, "jsActions");
       });
     });
-    handler.on("GetOutline", function wphSetupGetOutline(data) {
+    handler.on("GetOutline", function (data) {
       return pdfManager.ensureCatalog("documentOutline");
     });
     handler.on("GetOptionalContentConfig", function (data) {
@@ -362,13 +361,13 @@ class WorkerMessageHandler {
     handler.on("GetPermissions", function (data) {
       return pdfManager.ensureCatalog("permissions");
     });
-    handler.on("GetMetadata", function wphSetupGetMetadata(data) {
+    handler.on("GetMetadata", function (data) {
       return Promise.all([pdfManager.ensureDoc("documentInfo"), pdfManager.ensureCatalog("metadata")]);
     });
-    handler.on("GetMarkInfo", function wphSetupGetMarkInfo(data) {
+    handler.on("GetMarkInfo", function (data) {
       return pdfManager.ensureCatalog("markInfo");
     });
-    handler.on("GetData", function wphSetupGetData(data) {
+    handler.on("GetData", function (data) {
       return pdfManager.requestLoadedStream().then(function (stream) {
         return stream.bytes;
       });
@@ -441,6 +440,7 @@ class WorkerMessageHandler {
             return stream.bytes;
           }
         }
+        const needAppearances = acroFormRef && acroForm instanceof _primitives.Dict && newRefs.some(ref => ref.needAppearances);
         const xfa = acroForm instanceof _primitives.Dict && acroForm.get("XFA") || null;
         let xfaDatasetsRef = null;
         let hasXfaDatasetsEntry = false;
@@ -448,15 +448,13 @@ class WorkerMessageHandler {
           for (let i = 0, ii = xfa.length; i < ii; i += 2) {
             if (xfa[i] === "datasets") {
               xfaDatasetsRef = xfa[i + 1];
-              acroFormRef = null;
               hasXfaDatasetsEntry = true;
             }
           }
           if (xfaDatasetsRef === null) {
-            xfaDatasetsRef = xref.getNewRef();
+            xfaDatasetsRef = xref.getNewTemporaryRef();
           }
         } else if (xfa) {
-          acroFormRef = null;
           (0, _util.warn)("Unsupported XFA type.");
         }
         let newXrefInfo = Object.create(null);
@@ -473,7 +471,7 @@ class WorkerMessageHandler {
           newXrefInfo = {
             rootRef: xref.trailer.getRaw("Root") || null,
             encryptRef: xref.trailer.getRaw("Encrypt") || null,
-            newRef: xref.getNewRef(),
+            newRef: xref.getNewTemporaryRef(),
             infoRef: xref.trailer.getRaw("Info") || null,
             info: infoObj,
             fileIds: xref.trailer.get("ID") || null,
@@ -481,22 +479,26 @@ class WorkerMessageHandler {
             filename
           };
         }
-        xref.resetNewRef();
-        return (0, _writer.incrementalUpdate)({
-          originalData: stream.bytes,
-          xrefInfo: newXrefInfo,
-          newRefs,
-          xref,
-          hasXfa: !!xfa,
-          xfaDatasetsRef,
-          hasXfaDatasetsEntry,
-          acroFormRef,
-          acroForm,
-          xfaData
-        });
+        try {
+          return (0, _writer.incrementalUpdate)({
+            originalData: stream.bytes,
+            xrefInfo: newXrefInfo,
+            newRefs,
+            xref,
+            hasXfa: !!xfa,
+            xfaDatasetsRef,
+            hasXfaDatasetsEntry,
+            needAppearances,
+            acroFormRef,
+            acroForm,
+            xfaData
+          });
+        } finally {
+          xref.resetNewTemporaryRef();
+        }
       });
     });
-    handler.on("GetOperatorList", function wphSetupRenderPage(data, sink) {
+    handler.on("GetOperatorList", function (data, sink) {
       const pageIndex = data.pageIndex;
       pdfManager.getPage(pageIndex).then(function (page) {
         const task = new WorkerTask(`GetOperatorList: page ${pageIndex}`);
@@ -524,7 +526,7 @@ class WorkerMessageHandler {
         });
       });
     });
-    handler.on("GetTextContent", function wphExtractText(data, sink) {
+    handler.on("GetTextContent", function (data, sink) {
       const pageIndex = data.pageIndex;
       pdfManager.getPage(pageIndex).then(function (page) {
         const task = new WorkerTask("GetTextContent: page " + pageIndex);
@@ -551,7 +553,7 @@ class WorkerMessageHandler {
         });
       });
     });
-    handler.on("GetStructTree", function wphGetStructTree(data) {
+    handler.on("GetStructTree", function (data) {
       return pdfManager.getPage(data.pageIndex).then(function (page) {
         return pdfManager.ensure(page, "getStructTree");
       });
@@ -559,10 +561,10 @@ class WorkerMessageHandler {
     handler.on("FontFallback", function (data) {
       return pdfManager.fontFallback(data.id, handler);
     });
-    handler.on("Cleanup", function wphCleanup(data) {
+    handler.on("Cleanup", function (data) {
       return pdfManager.cleanup(true);
     });
-    handler.on("Terminate", function wphTerminate(data) {
+    handler.on("Terminate", function (data) {
       terminated = true;
       const waitOn = [];
       if (pdfManager) {
@@ -585,7 +587,7 @@ class WorkerMessageHandler {
         handler = null;
       });
     });
-    handler.on("Ready", function wphReady(data) {
+    handler.on("Ready", function (data) {
       setupDoc(docParams);
       docParams = null;
     });

+ 54 - 37
lib/core/writer.js

@@ -57,7 +57,7 @@ function writeStream(stream, buffer, transform) {
   if (transform !== null) {
     string = transform.encryptString(string);
   }
-  buffer.push(string, "\nendstream\n");
+  buffer.push(string, "\nendstream");
 }
 function writeArray(array, buffer, transform) {
   buffer.push("[");
@@ -83,7 +83,7 @@ function writeValue(value, buffer, transform) {
     if (transform !== null) {
       value = transform.encryptString(value);
     }
-    buffer.push(`(${(0, _util.escapeString)(value)})`);
+    buffer.push(`(${(0, _core_utils.escapeString)(value)})`);
   } else if (typeof value === "number") {
     buffer.push((0, _core_utils.numberToString)(value));
   } else if (typeof value === "boolean") {
@@ -159,43 +159,53 @@ function writeXFADataForAcroform(str, newRefs) {
   xml.documentElement.dump(buffer);
   return buffer.join("");
 }
-function updateXFA({
-  xfaData,
-  xfaDatasetsRef,
-  hasXfaDatasetsEntry,
-  acroFormRef,
-  acroForm,
-  newRefs,
+function updateAcroform({
   xref,
-  xrefInfo
+  acroForm,
+  acroFormRef,
+  hasXfa,
+  hasXfaDatasetsEntry,
+  xfaDatasetsRef,
+  needAppearances,
+  newRefs
 }) {
-  if (xref === null) {
+  if (hasXfa && !hasXfaDatasetsEntry && !xfaDatasetsRef) {
+    (0, _util.warn)("XFA - Cannot save it");
+  }
+  if (!needAppearances && (!hasXfa || !xfaDatasetsRef)) {
     return;
   }
-  if (!hasXfaDatasetsEntry) {
-    if (!acroFormRef) {
-      (0, _util.warn)("XFA - Cannot save it");
-      return;
-    }
-    const oldXfa = acroForm.get("XFA");
-    const newXfa = oldXfa.slice();
+  const dict = new _primitives.Dict(xref);
+  for (const key of acroForm.getKeys()) {
+    dict.set(key, acroForm.getRaw(key));
+  }
+  if (hasXfa && !hasXfaDatasetsEntry) {
+    const newXfa = acroForm.get("XFA").slice();
     newXfa.splice(2, 0, "datasets");
     newXfa.splice(3, 0, xfaDatasetsRef);
-    acroForm.set("XFA", newXfa);
-    const encrypt = xref.encrypt;
-    let transform = null;
-    if (encrypt) {
-      transform = encrypt.createCipherTransform(acroFormRef.num, acroFormRef.gen);
-    }
-    const buffer = [`${acroFormRef.num} ${acroFormRef.gen} obj\n`];
-    writeDict(acroForm, buffer, transform);
-    buffer.push("\n");
-    acroForm.set("XFA", oldXfa);
-    newRefs.push({
-      ref: acroFormRef,
-      data: buffer.join("")
-    });
+    dict.set("XFA", newXfa);
+  }
+  if (needAppearances) {
+    dict.set("NeedAppearances", true);
+  }
+  const encrypt = xref.encrypt;
+  let transform = null;
+  if (encrypt) {
+    transform = encrypt.createCipherTransform(acroFormRef.num, acroFormRef.gen);
   }
+  const buffer = [];
+  writeObject(acroFormRef, dict, buffer, transform);
+  newRefs.push({
+    ref: acroFormRef,
+    data: buffer.join("")
+  });
+}
+function updateXFA({
+  xfaData,
+  xfaDatasetsRef,
+  newRefs,
+  xref
+}) {
   if (xfaData === null) {
     const datasets = xref.fetchIfRef(xfaDatasetsRef);
     xfaData = writeXFADataForAcroform(datasets.getString(), newRefs);
@@ -219,20 +229,27 @@ function incrementalUpdate({
   hasXfa = false,
   xfaDatasetsRef = null,
   hasXfaDatasetsEntry = false,
+  needAppearances,
   acroFormRef = null,
   acroForm = null,
   xfaData = null
 }) {
+  updateAcroform({
+    xref,
+    acroForm,
+    acroFormRef,
+    hasXfa,
+    hasXfaDatasetsEntry,
+    xfaDatasetsRef,
+    needAppearances,
+    newRefs
+  });
   if (hasXfa) {
     updateXFA({
       xfaData,
       xfaDatasetsRef,
-      hasXfaDatasetsEntry,
-      acroFormRef,
-      acroForm,
       newRefs,
-      xref,
-      xrefInfo
+      xref
     });
   }
   const newXref = new _primitives.Dict(null);

+ 30 - 9
lib/core/xref.js

@@ -40,16 +40,25 @@ class XRef {
     this._cacheMap = new Map();
     this._pendingRefs = new _primitives.RefSet();
     this.stats = new _core_utils.DocStats(pdfManager.msgHandler);
-    this._newRefNum = null;
+    this._newPersistentRefNum = null;
+    this._newTemporaryRefNum = null;
   }
-  getNewRef() {
-    if (this._newRefNum === null) {
-      this._newRefNum = this.entries.length || 1;
+  getNewPersistentRef(obj) {
+    if (this._newPersistentRefNum === null) {
+      this._newPersistentRefNum = this.entries.length || 1;
     }
-    return _primitives.Ref.get(this._newRefNum++, 0);
+    const num = this._newPersistentRefNum++;
+    this._cacheMap.set(num, obj);
+    return _primitives.Ref.get(num, 0);
   }
-  resetNewRef() {
-    this._newRefNum = null;
+  getNewTemporaryRef() {
+    if (this._newTemporaryRefNum === null) {
+      this._newTemporaryRefNum = this.entries.length || 1;
+    }
+    return _primitives.Ref.get(this._newTemporaryRefNum++, 0);
+  }
+  resetNewTemporaryRef() {
+    this._newTemporaryRefNum = null;
   }
   setStartXRef(startXRef) {
     this.startXRefQueue = [startXRef];
@@ -382,7 +391,7 @@ class XRef {
             uncompressed: true
           };
         }
-        while (startPos < buffer.length) {
+        while (startPos < length) {
           const endPos = startPos + skipUntil(buffer, startPos, objBytes) + 4;
           contentLength = endPos - position;
           const checkPos = Math.max(endPos - CHECK_CONTENT_LENGTH, startPos);
@@ -408,7 +417,19 @@ class XRef {
         position += contentLength;
       } else if (token.startsWith("trailer") && (token.length === 7 || /\s/.test(token[7]))) {
         trailers.push(position);
-        position += skipUntil(buffer, position, startxrefBytes);
+        const contentLength = skipUntil(buffer, position, startxrefBytes);
+        if (position + contentLength >= length) {
+          const endPos = position + skipUntil(buffer, position, objBytes) + 4;
+          const checkPos = Math.max(endPos - CHECK_CONTENT_LENGTH, position);
+          const tokenStr = (0, _util.bytesToString)(buffer.subarray(checkPos, endPos));
+          const objToken = nestedObjRegExp.exec(tokenStr);
+          if (objToken && objToken[1]) {
+            (0, _util.warn)('indexObjects: Found first "obj" after "trailer", ' + 'caused by missing "startxref" -- trying to recover.');
+            position = endPos - objToken[1].length;
+            continue;
+          }
+        }
+        position += contentLength;
       } else {
         position += token.length + 1;
       }

+ 10 - 7
lib/display/annotation_layer.js

@@ -473,6 +473,9 @@ class LinkAnnotationElement extends AnnotationElement {
     }
     return this.container;
   }
+  #setInternalLink() {
+    this.container.setAttribute("data-internal-link", "");
+  }
   _bindLink(link, destination) {
     link.href = this.linkService.getDestinationHash(destination);
     link.onclick = () => {
@@ -482,7 +485,7 @@ class LinkAnnotationElement extends AnnotationElement {
       return false;
     };
     if (destination || destination === "") {
-      link.className = "internalLink";
+      this.#setInternalLink();
     }
   }
   _bindNamedAction(link, action) {
@@ -491,7 +494,7 @@ class LinkAnnotationElement extends AnnotationElement {
       this.linkService.executeNamedAction(action);
       return false;
     };
-    link.className = "internalLink";
+    this.#setInternalLink();
   }
   _bindAttachment(link, attachment) {
     link.href = this.linkService.getAnchorUrl("");
@@ -499,7 +502,7 @@ class LinkAnnotationElement extends AnnotationElement {
       this.downloadManager?.openOrDownloadData(this.container, attachment.content, attachment.filename);
       return false;
     };
-    link.className = "internalLink";
+    this.#setInternalLink();
   }
   #bindSetOCGState(link, action) {
     link.href = this.linkService.getAnchorUrl("");
@@ -507,7 +510,7 @@ class LinkAnnotationElement extends AnnotationElement {
       this.linkService.executeSetOCGState(action);
       return false;
     };
-    link.className = "internalLink";
+    this.#setInternalLink();
   }
   _bindJSAction(link, data) {
     link.href = this.linkService.getAnchorUrl("");
@@ -531,14 +534,14 @@ class LinkAnnotationElement extends AnnotationElement {
     if (!link.onclick) {
       link.onclick = () => false;
     }
-    link.className = "internalLink";
+    this.#setInternalLink();
   }
   _bindResetFormAction(link, resetForm) {
     const otherClickAction = link.onclick;
     if (!otherClickAction) {
       link.href = this.linkService.getAnchorUrl("");
     }
-    link.className = "internalLink";
+    this.#setInternalLink();
     if (!this._fieldObjects) {
       (0, _util.warn)(`_bindResetFormAction - "resetForm" action not supported, ` + "ensure that the `fieldObjects` parameter is provided.");
       if (!otherClickAction) {
@@ -1884,7 +1887,7 @@ class FileAttachmentAnnotationElement extends AnnotationElement {
       filename,
       content
     } = this.data.file;
-    this.filename = (0, _display_utils.getFilenameFromUrl)(filename);
+    this.filename = (0, _display_utils.getFilenameFromUrl)(filename, true);
     this.content = content;
     this.linkService.eventBus?.dispatch("fileattachmentannotation", {
       source: this,

+ 18 - 18
lib/display/annotation_storage.js

@@ -29,30 +29,30 @@ var _util = require("../shared/util.js");
 var _editor = require("./editor/editor.js");
 var _murmurhash = require("../shared/murmurhash3.js");
 class AnnotationStorage {
+  #modified = false;
+  #storage = new Map();
   constructor() {
-    this._storage = new Map();
-    this._modified = false;
     this.onSetModified = null;
     this.onResetModified = null;
     this.onAnnotationEditor = null;
   }
   getValue(key, defaultValue) {
-    const value = this._storage.get(key);
+    const value = this.#storage.get(key);
     if (value === undefined) {
       return defaultValue;
     }
     return Object.assign(defaultValue, value);
   }
   getRawValue(key) {
-    return this._storage.get(key);
+    return this.#storage.get(key);
   }
   remove(key) {
-    this._storage.delete(key);
-    if (this._storage.size === 0) {
+    this.#storage.delete(key);
+    if (this.#storage.size === 0) {
       this.resetModified();
     }
     if (typeof this.onAnnotationEditor === "function") {
-      for (const value of this._storage.values()) {
+      for (const value of this.#storage.values()) {
         if (value instanceof _editor.AnnotationEditor) {
           return;
         }
@@ -61,7 +61,7 @@ class AnnotationStorage {
     }
   }
   setValue(key, value) {
-    const obj = this._storage.get(key);
+    const obj = this.#storage.get(key);
     let modified = false;
     if (obj !== undefined) {
       for (const [entry, val] of Object.entries(value)) {
@@ -72,7 +72,7 @@ class AnnotationStorage {
       }
     } else {
       modified = true;
-      this._storage.set(key, value);
+      this.#storage.set(key, value);
     }
     if (modified) {
       this.#setModified();
@@ -82,25 +82,25 @@ class AnnotationStorage {
     }
   }
   has(key) {
-    return this._storage.has(key);
+    return this.#storage.has(key);
   }
   getAll() {
-    return this._storage.size > 0 ? (0, _util.objectFromMap)(this._storage) : null;
+    return this.#storage.size > 0 ? (0, _util.objectFromMap)(this.#storage) : null;
   }
   get size() {
-    return this._storage.size;
+    return this.#storage.size;
   }
   #setModified() {
-    if (!this._modified) {
-      this._modified = true;
+    if (!this.#modified) {
+      this.#modified = true;
       if (typeof this.onSetModified === "function") {
         this.onSetModified();
       }
     }
   }
   resetModified() {
-    if (this._modified) {
-      this._modified = false;
+    if (this.#modified) {
+      this.#modified = false;
       if (typeof this.onResetModified === "function") {
         this.onResetModified();
       }
@@ -110,11 +110,11 @@ class AnnotationStorage {
     return new PrintAnnotationStorage(this);
   }
   get serializable() {
-    if (this._storage.size === 0) {
+    if (this.#storage.size === 0) {
       return null;
     }
     const clone = new Map();
-    for (const [key, val] of this._storage) {
+    for (const [key, val] of this.#storage) {
       const serialized = val instanceof _editor.AnnotationEditor ? val.serialize() : val;
       if (serialized) {
         clone.set(key, serialized);

+ 6 - 4
lib/display/api.js

@@ -240,7 +240,7 @@ async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
   }
   const workerId = await worker.messageHandler.sendWithPromise("GetDocRequest", {
     docId,
-    apiVersion: '3.0.279',
+    apiVersion: '3.1.81',
     data: source.data,
     password: source.password,
     disableAutoFetch: source.disableAutoFetch,
@@ -1829,7 +1829,9 @@ class InternalRenderTask {
       transform,
       background
     } = this.params;
-    this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, optionalContentConfig, this.annotationCanvasMap, this.pageColors);
+    this.gfx = new _canvas.CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, {
+      optionalContentConfig
+    }, this.annotationCanvasMap, this.pageColors);
     this.gfx.beginDrawing({
       transform,
       viewport,
@@ -1899,7 +1901,7 @@ class InternalRenderTask {
     }
   }
 }
-const version = '3.0.279';
+const version = '3.1.81';
 exports.version = version;
-const build = 'd0823066c';
+const build = '0766898d5';
 exports.build = build;

+ 23 - 4
lib/display/canvas.js

@@ -730,7 +730,10 @@ const LINE_JOIN_STYLES = ["miter", "round", "bevel"];
 const NORMAL_CLIP = {};
 const EO_CLIP = {};
 class CanvasGraphics {
-  constructor(canvasCtx, commonObjs, objs, canvasFactory, optionalContentConfig, annotationCanvasMap, pageColors) {
+  constructor(canvasCtx, commonObjs, objs, canvasFactory, {
+    optionalContentConfig,
+    markedContentStack = null
+  }, annotationCanvasMap, pageColors) {
     this.ctx = canvasCtx;
     this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height);
     this.stateStack = [];
@@ -751,7 +754,7 @@ class CanvasGraphics {
     this.tempSMask = null;
     this.suspendedCtx = null;
     this.contentVisible = true;
-    this.markedContentStack = [];
+    this.markedContentStack = markedContentStack || [];
     this.optionalContentConfig = optionalContentConfig;
     this.cachedCanvases = new CachedCanvases(this.canvasFactory);
     this.cachedPatterns = new Map();
@@ -1551,6 +1554,19 @@ class CanvasGraphics {
       lineWidth /= fontSizeScale;
     }
     ctx.lineWidth = lineWidth;
+    if (font.isInvalidPDFjsFont) {
+      const chars = [];
+      let width = 0;
+      for (const glyph of glyphs) {
+        chars.push(glyph.unicode);
+        width += glyph.width;
+      }
+      ctx.fillText(chars.join(""), 0, 0);
+      current.x += width * widthAdvanceScale * textHScale;
+      ctx.restore();
+      this.compose();
+      return undefined;
+    }
     let x = 0,
       i;
     for (i = 0; i < glyphsLength; ++i) {
@@ -1686,7 +1702,10 @@ class CanvasGraphics {
       const baseTransform = this.baseTransform || (0, _display_utils.getCurrentTransform)(this.ctx);
       const canvasGraphicsFactory = {
         createCanvasGraphics: ctx => {
-          return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory);
+          return new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory, {
+            optionalContentConfig: this.optionalContentConfig,
+            markedContentStack: this.markedContentStack
+          });
         }
       };
       pattern = new _pattern_helper.TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, baseTransform);
@@ -1974,7 +1993,7 @@ class CanvasGraphics {
     const currentTransform = (0, _display_utils.getCurrentTransform)(ctx);
     ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0);
     const mask = this._createMaskCanvas(img);
-    ctx.setTransform(1, 0, 0, 1, 0, 0);
+    ctx.setTransform(1, 0, 0, 1, mask.offsetX - currentTransform[4], mask.offsetY - currentTransform[5]);
     for (let i = 0, ii = positions.length; i < ii; i += 2) {
       const trans = _util.Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]);
       const [x, y] = _util.Util.applyTransform([0, 0], trans);

+ 17 - 17
lib/display/display_utils.js

@@ -238,11 +238,11 @@ function isDataScheme(url) {
 function isPdfFile(filename) {
   return typeof filename === "string" && /\.pdf$/i.test(filename);
 }
-function getFilenameFromUrl(url) {
-  const anchor = url.indexOf("#");
-  const query = url.indexOf("?");
-  const end = Math.min(anchor > 0 ? anchor : url.length, query > 0 ? query : url.length);
-  return url.substring(url.lastIndexOf("/", end) + 1, end);
+function getFilenameFromUrl(url, onlyStripPath = false) {
+  if (!onlyStripPath) {
+    [url] = url.split(/[#?]/, 1);
+  }
+  return url.substring(url.lastIndexOf("/") + 1);
 }
 function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {
   if (typeof url !== "string") {
@@ -267,10 +267,8 @@ function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {
   return suggestedFilename || defaultFilename;
 }
 class StatTimer {
-  constructor() {
-    this.started = Object.create(null);
-    this.times = [];
-  }
+  started = Object.create(null);
+  times = [];
   time(name) {
     if (name in this.started) {
       (0, _util.warn)(`Timer is already running for ${name}`);
@@ -291,15 +289,17 @@ class StatTimer {
   toString() {
     const outBuf = [];
     let longest = 0;
-    for (const time of this.times) {
-      const name = time.name;
-      if (name.length > longest) {
-        longest = name.length;
-      }
+    for (const {
+      name
+    } of this.times) {
+      longest = Math.max(name.length, longest);
     }
-    for (const time of this.times) {
-      const duration = time.end - time.start;
-      outBuf.push(`${time.name.padEnd(longest)} ${duration}ms\n`);
+    for (const {
+      name,
+      start,
+      end
+    } of this.times) {
+      outBuf.push(`${name.padEnd(longest)} ${end - start}ms\n`);
     }
     return outBuf.join("");
   }

+ 1 - 6
lib/display/editor/freetext.js

@@ -197,12 +197,7 @@ class FreeTextEditor extends _editor.AnnotationEditor {
     }
     const buffer = [];
     for (const div of divs) {
-      const first = div.firstChild;
-      if (first?.nodeName === "#text") {
-        buffer.push(first.data);
-      } else {
-        buffer.push("");
-      }
+      buffer.push(div.innerText.replace(/\r\n?|\n/, ""));
     }
     return buffer.join("\n");
   }

+ 2 - 1
lib/display/text_layer.js

@@ -27,6 +27,7 @@ Object.defineProperty(exports, "__esModule", {
 exports.TextLayerRenderTask = void 0;
 exports.renderTextLayer = renderTextLayer;
 var _util = require("../shared/util.js");
+var _display_utils = require("./display_utils.js");
 const MAX_TEXT_DIVS_TO_RENDER = 100000;
 const DEFAULT_FONT_SIZE = 30;
 const DEFAULT_FONT_ASCENT = 0.8;
@@ -185,7 +186,6 @@ class TextLayerRenderTask {
     this._canceled = false;
     this._capability = (0, _util.createPromiseCapability)();
     this._renderTimer = null;
-    this._bounds = [];
     this._devicePixelRatio = globalThis.devicePixelRatio || 1;
     this._capability.promise.finally(() => {
       this._textDivProperties = null;
@@ -306,6 +306,7 @@ class TextLayerRenderTask {
       if (!timeout) {
         render(this);
       } else {
+        (0, _display_utils.deprecated)("The TextLayerRender `timeout` parameter will be removed in the " + "future, since streaming of textContent has made it obsolete.");
         this._renderTimer = setTimeout(() => {
           render(this);
           this._renderTimer = null;

+ 2 - 2
lib/pdf.js

@@ -251,8 +251,8 @@ var _is_node = require("./shared/is_node.js");
 var _text_layer = require("./display/text_layer.js");
 var _svg = require("./display/svg.js");
 var _xfa_layer = require("./display/xfa_layer.js");
-const pdfjsVersion = '3.0.279';
-const pdfjsBuild = 'd0823066c';
+const pdfjsVersion = '3.1.81';
+const pdfjsBuild = '0766898d5';
 {
   if (_is_node.isNodeJS) {
     const {

Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
lib/pdf.sandbox.js


+ 2 - 2
lib/pdf.worker.js

@@ -31,5 +31,5 @@ Object.defineProperty(exports, "WorkerMessageHandler", {
   }
 });
 var _worker = require("./core/worker.js");
-const pdfjsVersion = '3.0.279';
-const pdfjsBuild = 'd0823066c';
+const pdfjsVersion = '3.1.81';
+const pdfjsBuild = '0766898d5';

+ 1 - 3
lib/shared/murmurhash3.js

@@ -114,9 +114,7 @@ class MurmurHash3_64 {
     h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW;
     h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16;
     h1 ^= h2 >>> 1;
-    const hex1 = (h1 >>> 0).toString(16),
-      hex2 = (h2 >>> 0).toString(16);
-    return hex1.padStart(8, "0") + hex2.padStart(8, "0");
+    return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0");
   }
 }
 exports.MurmurHash3_64 = MurmurHash3_64;

+ 6 - 27
lib/shared/util.js

@@ -24,20 +24,18 @@
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMode = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;
+exports.VerbosityLevel = exports.Util = exports.UnknownErrorException = exports.UnexpectedResponseException = exports.UNSUPPORTED_FEATURES = exports.TextRenderingMode = exports.StreamType = exports.RenderingIntentFlag = exports.PermissionFlag = exports.PasswordResponses = exports.PasswordException = exports.PageActionEventType = exports.OPS = exports.MissingPDFException = exports.LINE_FACTOR = exports.LINE_DESCENT_FACTOR = exports.InvalidPDFException = exports.ImageKind = exports.IDENTITY_MATRIX = exports.FormatError = exports.FontType = exports.FeatureTest = exports.FONT_IDENTITY_MATRIX = exports.DocumentActionEventType = exports.CMapCompressionType = exports.BaseException = exports.BASELINE_FACTOR = exports.AnnotationType = exports.AnnotationStateModelType = exports.AnnotationReviewState = exports.AnnotationReplyType = exports.AnnotationMode = exports.AnnotationMarkedState = exports.AnnotationFlag = exports.AnnotationFieldFlag = exports.AnnotationEditorType = exports.AnnotationEditorPrefix = exports.AnnotationEditorParamsType = exports.AnnotationBorderStyleType = exports.AnnotationActionEventType = exports.AbortException = void 0;
 exports.arrayByteLength = arrayByteLength;
 exports.arraysToBytes = arraysToBytes;
 exports.assert = assert;
 exports.bytesToString = bytesToString;
 exports.createPromiseCapability = createPromiseCapability;
 exports.createValidAbsoluteUrl = createValidAbsoluteUrl;
-exports.escapeString = escapeString;
 exports.getModificationDate = getModificationDate;
 exports.getVerbosityLevel = getVerbosityLevel;
 exports.info = info;
 exports.isArrayBuffer = isArrayBuffer;
 exports.isArrayEqual = isArrayEqual;
-exports.isAscii = isAscii;
 exports.objectFromMap = objectFromMap;
 exports.objectSize = objectSize;
 exports.setVerbosityLevel = setVerbosityLevel;
@@ -45,7 +43,6 @@ exports.shadow = shadow;
 exports.string32 = string32;
 exports.stringToBytes = stringToBytes;
 exports.stringToPDFString = stringToPDFString;
-exports.stringToUTF16BEString = stringToUTF16BEString;
 exports.stringToUTF8String = stringToUTF8String;
 exports.unreachable = unreachable;
 exports.utf8StringToString = utf8StringToString;
@@ -59,10 +56,13 @@ const LINE_FACTOR = 1.35;
 exports.LINE_FACTOR = LINE_FACTOR;
 const LINE_DESCENT_FACTOR = 0.35;
 exports.LINE_DESCENT_FACTOR = LINE_DESCENT_FACTOR;
+const BASELINE_FACTOR = LINE_DESCENT_FACTOR / LINE_FACTOR;
+exports.BASELINE_FACTOR = BASELINE_FACTOR;
 const RenderingIntentFlag = {
   ANY: 0x01,
   DISPLAY: 0x02,
   PRINT: 0x04,
+  SAVE: 0x08,
   ANNOTATIONS_FORMS: 0x10,
   ANNOTATIONS_STORAGE: 0x20,
   ANNOTATIONS_DISABLE: 0x40,
@@ -474,10 +474,10 @@ function createValidAbsoluteUrl(url, baseUrl = null, options = null) {
   } catch (ex) {}
   return null;
 }
-function shadow(obj, prop, value) {
+function shadow(obj, prop, value, nonSerializable = false) {
   Object.defineProperty(obj, prop, {
     value,
-    enumerable: true,
+    enumerable: !nonSerializable,
     configurable: true,
     writable: false
   });
@@ -840,27 +840,6 @@ function stringToPDFString(str) {
   }
   return strBuf.join("");
 }
-function escapeString(str) {
-  return str.replace(/([()\\\n\r])/g, match => {
-    if (match === "\n") {
-      return "\\n";
-    } else if (match === "\r") {
-      return "\\r";
-    }
-    return `\\${match}`;
-  });
-}
-function isAscii(str) {
-  return /^[\x00-\x7F]*$/.test(str);
-}
-function stringToUTF16BEString(str) {
-  const buf = ["\xFE\xFF"];
-  for (let i = 0, ii = str.length; i < ii; i++) {
-    const char = str.charCodeAt(i);
-    buf.push(String.fromCharCode(char >> 8 & 0xff), String.fromCharCode(char & 0xff));
-  }
-  return buf.join("");
-}
 function stringToUTF8String(str) {
   return decodeURIComponent(escape(str));
 }

+ 33 - 30
lib/test/unit/annotation_spec.js

@@ -39,6 +39,9 @@ describe("annotation", function () {
           acroForm: new _primitives.Dict()
         }
       };
+      this.evaluatorOptions = {
+        isOffscreenCanvasSupported: false
+      };
     }
     ensure(obj, prop, args) {
       return new Promise(function (resolve) {
@@ -1315,8 +1318,8 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "test\\print"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
-      expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm" + " 2 3.04 Td (test\\\\print) Tj ET Q EMC");
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
+      expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm" + " 2 3.07 Td (test\\\\print) Tj ET Q EMC");
     });
     it("should render regular text in Japanese for printing", async function () {
       textWidgetDict.get("DR").get("Font").set("Goth", gothRefObj.ref);
@@ -1333,9 +1336,9 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "こんにちは世界の"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
       const utf16String = "\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f\x4e\x16\x75\x4c\x30\x6e";
-      expect(appearance).toEqual("/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 0 Tm" + ` 2 2 Td (${utf16String}) Tj ET Q EMC`);
+      expect(appearance).toEqual("/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 0 Tm" + ` 2 3.07 Td (${utf16String}) Tj ET Q EMC`);
     });
     it("should render regular text for printing using normal appearance", async function () {
       const textWidgetRef = _primitives.Ref.get(271, 0);
@@ -1375,8 +1378,8 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "test (print)"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
-      expect(appearance).toEqual("/Tx BMC q BT /Helv 5.92 Tf 0 g 1 0 0 1 0 0 Tm" + " 2 3.23 Td (test \\(print\\)) Tj ET Q EMC");
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
+      expect(appearance).toEqual("/Tx BMC q BT /Helv 5.92 Tf 0 g 1 0 0 1 0 0 Tm" + " 2 3.07 Td (test \\(print\\)) Tj ET Q EMC");
     });
     it("should render auto-sized text in Japanese for printing", async function () {
       textWidgetDict.get("DR").get("Font").set("Goth", gothRefObj.ref);
@@ -1393,9 +1396,9 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "こんにちは世界の"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
       const utf16String = "\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f\x4e\x16\x75\x4c\x30\x6e";
-      expect(appearance).toEqual("/Tx BMC q BT /Goth 3.5 Tf 0 g 1 0 0 1 0 0 Tm" + ` 2 2 Td (${utf16String}) Tj ET Q EMC`);
+      expect(appearance).toEqual("/Tx BMC q BT /Goth 5.92 Tf 0 g 1 0 0 1 0 0 Tm" + ` 2 3.07 Td (${utf16String}) Tj ET Q EMC`);
     });
     it("should not render a password for printing", async function () {
       textWidgetDict.set("Ff", _util.AnnotationFieldFlag.PASSWORD);
@@ -1411,7 +1414,7 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "mypassword"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
       expect(appearance).toEqual(null);
     });
     it("should render multiline text for printing", async function () {
@@ -1428,8 +1431,8 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "a aa aaa aaaa aaaaa aaaaaa " + "pneumonoultramicroscopicsilicovolcanoconiosis"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
-      expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 10 Tm " + "2 -5 Td (a aa aaa ) Tj\n" + "0 -5 Td (aaaa aaaaa ) Tj\n" + "0 -5 Td (aaaaaa ) Tj\n" + "0 -5 Td (pneumonoultr) Tj\n" + "0 -5 Td (amicroscopi) Tj\n" + "0 -5 Td (csilicovolca) Tj\n" + "0 -5 Td (noconiosis) Tj ET Q EMC");
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
+      expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 10 Tm " + "2 -6.93 Td (a aa aaa ) Tj\n" + "0 -8 Td (aaaa aaaaa ) Tj\n" + "0 -8 Td (aaaaaa ) Tj\n" + "0 -8 Td (pneumonoultr) Tj\n" + "0 -8 Td (amicroscopi) Tj\n" + "0 -8 Td (csilicovolca) Tj\n" + "0 -8 Td (noconiosis) Tj ET Q EMC");
     });
     it("should render multiline text in Japanese for printing", async function () {
       textWidgetDict.set("Ff", _util.AnnotationFieldFlag.MULTILINE);
@@ -1447,8 +1450,8 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "こんにちは世界の"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
-      expect(appearance).toEqual("/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 10 Tm " + "2 -5 Td (\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f) Tj\n" + "0 -5 Td (\x4e\x16\x75\x4c\x30\x6e) Tj ET Q EMC");
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
+      expect(appearance).toEqual("/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 10 Tm " + "2 -6.93 Td (\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f) Tj\n" + "0 -8 Td (\x4e\x16\x75\x4c\x30\x6e) Tj ET Q EMC");
     });
     it("should render multiline text with various EOL for printing", async function () {
       textWidgetDict.set("Ff", _util.AnnotationFieldFlag.MULTILINE);
@@ -1460,13 +1463,13 @@ describe("annotation", function () {
       }, helvRefObj]);
       const task = new _worker.WorkerTask("test print");
       partialEvaluator.xref = xref;
-      const expectedAppearance = "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 10 Tm " + "2 -5 Td " + "(Lorem ipsum dolor sit amet, consectetur adipiscing elit.) Tj\n" + "0 -5 Td " + "(Aliquam vitae felis ac lectus bibendum ultricies quis non) Tj\n" + "0 -5 Td " + "( diam.) Tj\n" + "0 -5 Td " + "(Morbi id porttitor quam, a iaculis dui.) Tj\n" + "0 -5 Td " + "(Pellentesque habitant morbi tristique senectus et netus ) Tj\n" + "0 -5 Td " + "(et malesuada fames ac turpis egestas.) Tj\n" + "0 -5 Td () Tj\n" + "0 -5 Td () Tj\n" + "0 -5 Td " + "(Nulla consectetur, ligula in tincidunt placerat, velit ) Tj\n" + "0 -5 Td " + "(augue consectetur orci, sed mattis libero nunc ut massa.) Tj\n" + "0 -5 Td " + "(Etiam facilisis tempus interdum.) Tj ET Q EMC";
+      const expectedAppearance = "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 10 Tm " + "2 -6.93 Td " + "(Lorem ipsum dolor sit amet, consectetur adipiscing elit.) Tj\n" + "0 -8 Td " + "(Aliquam vitae felis ac lectus bibendum ultricies quis non) Tj\n" + "0 -8 Td " + "( diam.) Tj\n" + "0 -8 Td " + "(Morbi id porttitor quam, a iaculis dui.) Tj\n" + "0 -8 Td " + "(Pellentesque habitant morbi tristique senectus et netus ) Tj\n" + "0 -8 Td " + "(et malesuada fames ac turpis egestas.) Tj\n" + "0 -8 Td () Tj\n" + "0 -8 Td () Tj\n" + "0 -8 Td " + "(Nulla consectetur, ligula in tincidunt placerat, velit ) Tj\n" + "0 -8 Td " + "(augue consectetur orci, sed mattis libero nunc ut massa.) Tj\n" + "0 -8 Td " + "(Etiam facilisis tempus interdum.) Tj ET Q EMC";
       const annotation = await _annotation.AnnotationFactory.create(xref, textWidgetRef, pdfManagerMock, idFactoryMock);
       const annotationStorage = new Map();
       annotationStorage.set(annotation.data.id, {
         value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\r" + "Aliquam vitae felis ac lectus bibendum ultricies quis non diam.\n" + "Morbi id porttitor quam, a iaculis dui.\r\n" + "Pellentesque habitant morbi tristique senectus et " + "netus et malesuada fames ac turpis egestas.\n\r\n\r" + "Nulla consectetur, ligula in tincidunt placerat, " + "velit augue consectetur orci, sed mattis libero nunc ut massa.\r" + "Etiam facilisis tempus interdum."
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
       expect(appearance).toEqual(expectedAppearance);
     });
     it("should render comb for printing", async function () {
@@ -1484,8 +1487,8 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "aa(aa)a\\"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
-      expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 2 3.035 Tm" + " (a) Tj 8 0 Td (a) Tj 8 0 Td (\\() Tj" + " 8 0 Td (a) Tj 8 0 Td (a) Tj" + " 8 0 Td (\\)) Tj 8 0 Td (a) Tj" + " 8 0 Td (\\\\) Tj ET Q EMC");
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
+      expect(appearance).toEqual("/Tx BMC q BT /Helv 5 Tf 1 0 0 1 2 3.07 Tm" + " (a) Tj 8 0 Td (a) Tj 8 0 Td (\\() Tj" + " 8 0 Td (a) Tj 8 0 Td (a) Tj" + " 8 0 Td (\\)) Tj 8 0 Td (a) Tj" + " 8 0 Td (\\\\) Tj ET Q EMC");
     });
     it("should render comb with Japanese text for printing", async function () {
       textWidgetDict.set("Ff", _util.AnnotationFieldFlag.COMB);
@@ -1505,8 +1508,8 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "こんにちは世界の"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
-      expect(appearance).toEqual("/Tx BMC q BT /Goth 5 Tf 1 0 0 1 2 2 Tm" + " (\x30\x53) Tj 8 0 Td (\x30\x93) Tj 8 0 Td (\x30\x6b) Tj" + " 8 0 Td (\x30\x61) Tj 8 0 Td (\x30\x6f) Tj" + " 8 0 Td (\x4e\x16) Tj 8 0 Td (\x75\x4c) Tj" + " 8 0 Td (\x30\x6e) Tj ET Q EMC");
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
+      expect(appearance).toEqual("/Tx BMC q BT /Goth 5 Tf 1 0 0 1 2 3.07 Tm" + " (\x30\x53) Tj 8 0 Td (\x30\x93) Tj 8 0 Td (\x30\x6b) Tj" + " 8 0 Td (\x30\x61) Tj 8 0 Td (\x30\x6f) Tj" + " 8 0 Td (\x4e\x16) Tj 8 0 Td (\x75\x4c) Tj" + " 8 0 Td (\x30\x6e) Tj ET Q EMC");
     });
     it("should save text", async function () {
       const textWidgetRef = _primitives.Ref.get(123, 0);
@@ -1528,7 +1531,7 @@ describe("annotation", function () {
       expect(newData.ref).toEqual(_primitives.Ref.get(2, 0));
       oldData.data = oldData.data.replace(/\(D:\d+\)/, "(date)");
       expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Tx /DA (/Helv 5 Tf) /DR " + "<< /Font << /Helv 314 0 R>>>> /Rect [0 0 32 10] " + "/V (hello world) /AP << /N 2 0 R>> /M (date)>>\nendobj\n");
-      expect(newData.data).toEqual("2 0 obj\n<< /Length 74 /Subtype /Form /Resources " + "<< /Font << /Helv 314 0 R>>>> /BBox [0 0 32 10]>> stream\n" + "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm 2 3.04 Td (hello world) Tj " + "ET Q EMC\nendstream\nendobj\n");
+      expect(newData.data).toEqual("2 0 obj\n<< /Length 74 /Subtype /Form /Resources " + "<< /Font << /Helv 314 0 R>>>> /BBox [0 0 32 10]>> stream\n" + "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm 2 3.07 Td (hello world) Tj " + "ET Q EMC\nendstream\nendobj\n");
     });
     it("should save rotated text", async function () {
       const textWidgetRef = _primitives.Ref.get(123, 0);
@@ -1550,8 +1553,8 @@ describe("annotation", function () {
       expect(oldData.ref).toEqual(_primitives.Ref.get(123, 0));
       expect(newData.ref).toEqual(_primitives.Ref.get(2, 0));
       oldData.data = oldData.data.replace(/\(D:\d+\)/, "(date)");
-      expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Tx /DA (/Helv 5 Tf) /DR " + "<< /Font << /Helv 314 0 R>>>> /Rect [0 0 32 10] " + "/V (hello world) /AP << /N 2 0 R>> /M (date) /MK << /R 90>>>>\nendobj\n");
-      expect(newData.data).toEqual("2 0 obj\n<< /Length 74 /Subtype /Form /Resources " + "<< /Font << /Helv 314 0 R>>>> /BBox [0 0 32 10] /Matrix [0 1 -1 0 32 0]>> stream\n" + "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm 2 3.04 Td (hello world) Tj " + "ET Q EMC\nendstream\nendobj\n");
+      expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Tx /DA (/Helv 5 Tf) /DR " + "<< /Font << /Helv 314 0 R>>>> /Rect [0 0 32 10] " + "/V (hello world) /MK << /R 90>> /AP << /N 2 0 R>> /M (date)>>\nendobj\n");
+      expect(newData.data).toEqual("2 0 obj\n<< /Length 74 /Subtype /Form /Resources " + "<< /Font << /Helv 314 0 R>>>> /BBox [0 0 32 10] /Matrix [0 1 -1 0 32 0]>> stream\n" + "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm 2 2.94 Td (hello world) Tj " + "ET Q EMC\nendstream\nendobj\n");
     });
     it("should get field object for usage in JS sandbox", async function () {
       const textWidgetRef = _primitives.Ref.get(123, 0);
@@ -1646,7 +1649,7 @@ describe("annotation", function () {
       expect(newData.ref).toEqual(_primitives.Ref.get(2, 0));
       oldData.data = oldData.data.replace(/\(D:\d+\)/, "(date)");
       expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Tx /DA (/Goth 5 Tf) /DR " + "<< /Font << /Helv 314 0 R /Goth 159 0 R>>>> /Rect [0 0 32 10] " + `/V (\xfe\xff${utf16String}) /AP << /N 2 0 R>> /M (date)>>\nendobj\n`);
-      expect(newData.data).toEqual("2 0 obj\n<< /Length 76 /Subtype /Form /Resources " + "<< /Font << /Helv 314 0 R /Goth 159 0 R>>>> /BBox [0 0 32 10]>> stream\n" + `/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 0 Tm 2 2 Td (${utf16String}) Tj ` + "ET Q EMC\nendstream\nendobj\n");
+      expect(newData.data).toEqual("2 0 obj\n<< /Length 79 /Subtype /Form /Resources " + "<< /Font << /Helv 314 0 R /Goth 159 0 R>>>> /BBox [0 0 32 10]>> stream\n" + `/Tx BMC q BT /Goth 5 Tf 1 0 0 1 0 0 Tm 2 3.07 Td (${utf16String}) Tj ` + "ET Q EMC\nendstream\nendobj\n");
     });
   });
   describe("ButtonWidgetAnnotation", function () {
@@ -2473,7 +2476,7 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: "a value"
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
       expect(appearance).toEqual(["/Tx BMC q", "1 1 32 10 re W n", "BT", "/Helv 5 Tf", "1 0 0 1 0 10 Tm", "ET Q EMC"].join("\n"));
     });
     it("should render choice with multiple selections but one is visible for printing", async function () {
@@ -2492,7 +2495,7 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: ["A", "C"]
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
       expect(appearance).toEqual(["/Tx BMC q", "1 1 32 10 re W n", "0.600006 0.756866 0.854904 rg", "1 3.25 32 6.75 re f", "BT", "/Helv 5 Tf", "1 0 0 1 0 10 Tm", "2 -5.88 Td (a) Tj", "0 -6.75 Td (b) Tj", "ET Q EMC"].join("\n"));
     });
     it("should render choice with multiple selections for printing", async function () {
@@ -2511,7 +2514,7 @@ describe("annotation", function () {
       annotationStorage.set(annotation.data.id, {
         value: ["B", "C"]
       });
-      const appearance = await annotation._getAppearance(partialEvaluator, task, annotationStorage);
+      const appearance = await annotation._getAppearance(partialEvaluator, task, _util.RenderingIntentFlag.PRINT, annotationStorage);
       expect(appearance).toEqual(["/Tx BMC q", "1 1 32 10 re W n", "0.600006 0.756866 0.854904 rg", "1 3.25 32 6.75 re f", "1 -3.5 32 6.75 re f", "BT", "/Helv 5 Tf", "1 0 0 1 0 10 Tm", "2 -5.88 Td (b) Tj", "0 -6.75 Td (c) Tj", "ET Q EMC"].join("\n"));
     });
     it("should save rotated choice", async function () {
@@ -2536,7 +2539,7 @@ describe("annotation", function () {
       expect(oldData.ref).toEqual(_primitives.Ref.get(123, 0));
       expect(newData.ref).toEqual(_primitives.Ref.get(2, 0));
       oldData.data = oldData.data.replace(/\(D:\d+\)/, "(date)");
-      expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Ch /DA (/Helv 5 Tf) /DR " + "<< /Font << /Helv 314 0 R>>>> " + "/Rect [0 0 32 10] /Opt [(A) (B) (C)] /V (C) " + "/AP << /N 2 0 R>> /M (date) /MK << /R 270>>>>\nendobj\n");
+      expect(oldData.data).toEqual("123 0 obj\n" + "<< /Type /Annot /Subtype /Widget /FT /Ch /DA (/Helv 5 Tf) /DR " + "<< /Font << /Helv 314 0 R>>>> " + "/Rect [0 0 32 10] /Opt [(A) (B) (C)] /V (C) " + "/MK << /R 270>> /AP << /N 2 0 R>> /M (date)>>\nendobj\n");
       expect(newData.data).toEqual(["2 0 obj", "<< /Length 170 /Subtype /Form /Resources << /Font << /Helv 314 0 R>>>> " + "/BBox [0 0 32 10] /Matrix [0 -1 1 0 0 10]>> stream", "/Tx BMC q", "1 1 10 32 re W n", "0.600006 0.756866 0.854904 rg", "1 11.75 10 6.75 re f", "BT", "/Helv 5 Tf", "1 0 0 1 0 32 Tm", "2 -5.88 Td (A) Tj", "0 -6.75 Td (B) Tj", "0 -6.75 Td (C) Tj", "ET Q EMC", "endstream", "endobj\n"].join("\n"));
     });
     it("should save choice", async function () {
@@ -2813,7 +2816,7 @@ describe("annotation", function () {
       const font = data.dependencies[0].data;
       expect(font).toEqual("1 0 obj\n" + "<< /BaseFont /Helvetica /Type /Font /Subtype /Type1 /Encoding " + "/WinAnsiEncoding>>\n" + "endobj\n");
       const appearance = data.dependencies[1].data;
-      expect(appearance).toEqual("3 0 obj\n" + "<< /FormType 1 /Subtype /Form /Type /XObject /BBox [0 0 44 44] " + "/Length 101 /Resources << /Font << /Helv 1 0 R>>>>>> stream\n" + "q\n" + "0 0 44 44 re W n\n" + "BT\n" + "1 0 0 1 0 47.5 Tm 0 Tc 0 g\n" + "/Helv 10 Tf\n" + "0 -13.5 Td (Hello PDF.js World!) Tj\n" + "ET\n" + "Q\n" + "endstream\n" + "\n" + "endobj\n");
+      expect(appearance).toEqual("3 0 obj\n" + "<< /FormType 1 /Subtype /Form /Type /XObject /BBox [0 0 44 44] " + "/Length 101 /Resources << /Font << /Helv 1 0 R>>>>>> stream\n" + "q\n" + "0 0 44 44 re W n\n" + "BT\n" + "1 0 0 1 0 47.5 Tm 0 Tc 0 g\n" + "/Helv 10 Tf\n" + "0 -13.5 Td (Hello PDF.js World!) Tj\n" + "ET\n" + "Q\n" + "endstream\n" + "endobj\n");
     });
     it("should render an added FreeText annotation for printing", async function () {
       partialEvaluator.xref = new _test_utils.XRefMock();
@@ -2928,7 +2931,7 @@ describe("annotation", function () {
       const base = data.annotations[0].data.replace(/\(D:\d+\)/, "(date)");
       expect(base).toEqual("1 0 obj\n" + "<< /Type /Annot /Subtype /Ink /CreationDate (date) /Rect [12 34 56 78] " + "/InkList [[1 2 3 4 5 6 7 8] [91 92 93 94 95 96 97 98]] /F 4 /Border [0 0 0] " + "/Rotate 0 /AP << /N 2 0 R>>>>\n" + "endobj\n");
       const appearance = data.dependencies[0].data;
-      expect(appearance).toEqual("2 0 obj\n" + "<< /FormType 1 /Subtype /Form /Type /XObject /BBox [0 0 44 44] /Length 129>> stream\n" + "1 w 1 J 1 j\n" + "0 G\n" + "10 11 m\n" + "12 13 14 15 16 17 c\n" + "22 23 24 25 26 27 c\n" + "S\n" + "910 911 m\n" + "912 913 914 915 916 917 c\n" + "922 923 924 925 926 927 c\n" + "S\n" + "endstream\n" + "\n" + "endobj\n");
+      expect(appearance).toEqual("2 0 obj\n" + "<< /FormType 1 /Subtype /Form /Type /XObject /BBox [0 0 44 44] /Length 129>> stream\n" + "1 w 1 J 1 j\n" + "0 G\n" + "10 11 m\n" + "12 13 14 15 16 17 c\n" + "22 23 24 25 26 27 c\n" + "S\n" + "910 911 m\n" + "912 913 914 915 916 917 c\n" + "922 923 924 925 926 927 c\n" + "S\n" + "endstream\n" + "endobj\n");
     });
     it("should create a new Ink annotation with some transparency", async function () {
       partialEvaluator.xref = new _test_utils.XRefMock();
@@ -2951,7 +2954,7 @@ describe("annotation", function () {
       const base = data.annotations[0].data.replace(/\(D:\d+\)/, "(date)");
       expect(base).toEqual("1 0 obj\n" + "<< /Type /Annot /Subtype /Ink /CreationDate (date) /Rect [12 34 56 78] " + "/InkList [[1 2 3 4 5 6 7 8] [91 92 93 94 95 96 97 98]] /F 4 /Border [0 0 0] " + "/Rotate 0 /AP << /N 2 0 R>>>>\n" + "endobj\n");
       const appearance = data.dependencies[0].data;
-      expect(appearance).toEqual("2 0 obj\n" + "<< /FormType 1 /Subtype /Form /Type /XObject /BBox [0 0 44 44] /Length 136 /Resources " + "<< /ExtGState << /R0 << /CA 0.12 /Type /ExtGState>>>>>>>> stream\n" + "1 w 1 J 1 j\n" + "0 G\n" + "/R0 gs\n" + "10 11 m\n" + "12 13 14 15 16 17 c\n" + "22 23 24 25 26 27 c\n" + "S\n" + "910 911 m\n" + "912 913 914 915 916 917 c\n" + "922 923 924 925 926 927 c\n" + "S\n" + "endstream\n" + "\n" + "endobj\n");
+      expect(appearance).toEqual("2 0 obj\n" + "<< /FormType 1 /Subtype /Form /Type /XObject /BBox [0 0 44 44] /Length 136 /Resources " + "<< /ExtGState << /R0 << /CA 0.12 /Type /ExtGState>>>>>>>> stream\n" + "1 w 1 J 1 j\n" + "0 G\n" + "/R0 gs\n" + "10 11 m\n" + "12 13 14 15 16 17 c\n" + "22 23 24 25 26 27 c\n" + "S\n" + "910 911 m\n" + "912 913 914 915 916 917 c\n" + "922 923 924 925 926 927 c\n" + "S\n" + "endstream\n" + "endobj\n");
     });
     it("should render an added Ink annotation for printing", async function () {
       partialEvaluator.xref = new _test_utils.XRefMock();

+ 37 - 9
lib/test/unit/api_spec.js

@@ -372,27 +372,40 @@ describe("api", function () {
     it("creates pdf doc from PDF files, with bad /Pages tree /Count", async function () {
       const loadingTask1 = (0, _api.getDocument)((0, _test_utils.buildGetDocumentParams)("poppler-67295-0.pdf"));
       const loadingTask2 = (0, _api.getDocument)((0, _test_utils.buildGetDocumentParams)("poppler-85140-0.pdf"));
+      const loadingTask3 = (0, _api.getDocument)((0, _test_utils.buildGetDocumentParams)("poppler-85140-0.pdf", {
+        stopAtErrors: true
+      }));
       expect(loadingTask1 instanceof _api.PDFDocumentLoadingTask).toEqual(true);
       expect(loadingTask2 instanceof _api.PDFDocumentLoadingTask).toEqual(true);
+      expect(loadingTask3 instanceof _api.PDFDocumentLoadingTask).toEqual(true);
       const pdfDocument1 = await loadingTask1.promise;
       const pdfDocument2 = await loadingTask2.promise;
+      const pdfDocument3 = await loadingTask3.promise;
       expect(pdfDocument1.numPages).toEqual(1);
       expect(pdfDocument2.numPages).toEqual(1);
-      const page = await pdfDocument1.getPage(1);
-      expect(page instanceof _api.PDFPageProxy).toEqual(true);
-      const opList = await page.getOperatorList();
-      expect(opList.fnArray.length).toBeGreaterThan(5);
-      expect(opList.argsArray.length).toBeGreaterThan(5);
-      expect(opList.lastChunk).toEqual(true);
-      expect(opList.separateAnnots).toEqual(null);
+      expect(pdfDocument3.numPages).toEqual(1);
+      const pageA = await pdfDocument1.getPage(1);
+      expect(pageA instanceof _api.PDFPageProxy).toEqual(true);
+      const opListA = await pageA.getOperatorList();
+      expect(opListA.fnArray.length).toBeGreaterThan(5);
+      expect(opListA.argsArray.length).toBeGreaterThan(5);
+      expect(opListA.lastChunk).toEqual(true);
+      expect(opListA.separateAnnots).toEqual(null);
+      const pageB = await pdfDocument2.getPage(1);
+      expect(pageB instanceof _api.PDFPageProxy).toEqual(true);
+      const opListB = await pageB.getOperatorList();
+      expect(opListB.fnArray.length).toBe(0);
+      expect(opListB.argsArray.length).toBe(0);
+      expect(opListB.lastChunk).toEqual(true);
+      expect(opListB.separateAnnots).toEqual(null);
       try {
-        await pdfDocument2.getPage(1);
+        await pdfDocument3.getPage(1);
         expect(false).toEqual(true);
       } catch (reason) {
         expect(reason instanceof _util.UnknownErrorException).toEqual(true);
         expect(reason.message).toEqual("Bad (uncompressed) XRef entry: 3R");
       }
-      await Promise.all([loadingTask1.destroy(), loadingTask2.destroy()]);
+      await Promise.all([loadingTask1.destroy(), loadingTask2.destroy(), loadingTask3.destroy()]);
     });
     it("creates pdf doc from PDF files, with circular references", async function () {
       const loadingTask1 = (0, _api.getDocument)((0, _test_utils.buildGetDocumentParams)("poppler-91414-0-53.pdf"));
@@ -453,6 +466,19 @@ describe("api", function () {
       expect(opList.lastChunk).toEqual(true);
       await loadingTask.destroy();
     });
+    it("creates pdf doc from PDF file, with incomplete trailer", async function () {
+      const loadingTask = (0, _api.getDocument)((0, _test_utils.buildGetDocumentParams)("issue15590.pdf"));
+      expect(loadingTask instanceof _api.PDFDocumentLoadingTask).toEqual(true);
+      const pdfDocument = await loadingTask.promise;
+      expect(pdfDocument.numPages).toEqual(1);
+      const jsActions = await pdfDocument.getJSActions();
+      expect(jsActions).toEqual({
+        OpenAction: ["func=function(){app.alert(1)};func();"]
+      });
+      const page = await pdfDocument.getPage(1);
+      expect(page instanceof _api.PDFPageProxy).toEqual(true);
+      await loadingTask.destroy();
+    });
   });
   describe("PDFWorker", function () {
     it("worker created or destroyed", async function () {
@@ -1583,6 +1609,8 @@ page 1 / 3`);
         descent: _is_node.isNodeJS ? NaN : -0.217,
         vertical: false
       });
+      await pdfPage.getOperatorList();
+      expect(pdfPage.commonObjs.has(fontName)).toEqual(true);
       await loadingTask.destroy();
     });
     it("gets text content, with no extra spaces (issue 13226)", async function () {

+ 28 - 0
lib/test/unit/core_utils_spec.js

@@ -212,6 +212,11 @@ describe("core_utils", function () {
       expect((0, _core_utils.escapePDFName)("#()<>[]{}/%")).toEqual("#23#28#29#3c#3e#5b#5d#7b#7d#2f#25");
     });
   });
+  describe("escapeString", function () {
+    it("should escape (, ), \\n, \\r, and \\", function () {
+      expect((0, _core_utils.escapeString)("((a\\a))\n(b(b\\b)\rb)")).toEqual("\\(\\(a\\\\a\\)\\)\\n\\(b\\(b\\\\b\\)\\rb\\)");
+    });
+  });
   describe("encodeToXmlString", function () {
     it("should get a correctly encoded string with some entities", function () {
       const str = "\"\u0397ell😂' & <W😂rld>";
@@ -296,4 +301,27 @@ describe("core_utils", function () {
       expect(cssFontInfo.italicAngle).toEqual("2.718");
     });
   });
+  describe("isAscii", function () {
+    it("handles ascii/non-ascii strings", function () {
+      expect((0, _core_utils.isAscii)("hello world")).toEqual(true);
+      expect((0, _core_utils.isAscii)("こんにちは世界の")).toEqual(false);
+      expect((0, _core_utils.isAscii)("hello world in Japanese is こんにちは世界の")).toEqual(false);
+    });
+  });
+  describe("stringToUTF16HexString", function () {
+    it("should encode a string in UTF16 hexadecimal format", function () {
+      expect((0, _core_utils.stringToUTF16HexString)("hello world")).toEqual("00680065006c006c006f00200077006f0072006c0064");
+      expect((0, _core_utils.stringToUTF16HexString)("こんにちは世界の")).toEqual("30533093306b3061306f4e16754c306e");
+    });
+  });
+  describe("stringToUTF16String", function () {
+    it("should encode a string in UTF16", function () {
+      expect((0, _core_utils.stringToUTF16String)("hello world")).toEqual("\0h\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d");
+      expect((0, _core_utils.stringToUTF16String)("こんにちは世界の")).toEqual("\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f\x4e\x16\x75\x4c\x30\x6e");
+    });
+    it("should encode a string in UTF16BE with a BOM", function () {
+      expect((0, _core_utils.stringToUTF16String)("hello world", true)).toEqual("\xfe\xff\0h\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d");
+      expect((0, _core_utils.stringToUTF16String)("こんにちは世界の", true)).toEqual("\xfe\xff\x30\x53\x30\x93\x30\x6b\x30\x61\x30\x6f\x4e\x16\x75\x4c\x30\x6e");
+    });
+  });
 });

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

@@ -167,6 +167,10 @@ describe("display_utils", function () {
       const url = "https://server.org/filename.pdf?foo=bar";
       expect((0, _display_utils.getFilenameFromUrl)(url)).toEqual("filename.pdf");
     });
+    it("should get the filename from a relative URL, keeping the anchor", function () {
+      const url = "../../part1#part2.pdf";
+      expect((0, _display_utils.getFilenameFromUrl)(url, true)).toEqual("part1#part2.pdf");
+    });
   });
   describe("getPdfFilenameFromUrl", function () {
     it("gets PDF filename", function () {

+ 5 - 0
lib/test/unit/document_spec.js

@@ -69,6 +69,11 @@ describe("document", function () {
             return value.apply(obj, args);
           }
           return value;
+        },
+        get evaluatorOptions() {
+          return {
+            isOffscreenCanvasSupported: false
+          };
         }
       };
       const pdfDocument = new _document.PDFDocument(pdfManager, stream);

+ 20 - 0
lib/test/unit/pdf_find_controller_spec.js

@@ -556,4 +556,24 @@ describe("pdf_find_controller", function () {
       pageMatchesLength: [[4]]
     });
   });
+  it("performs a search in a text containing fullwidth chars", async function () {
+    const {
+      eventBus,
+      pdfFindController
+    } = await initPdfFindController("issue15690.pdf");
+    await testSearch({
+      eventBus,
+      pdfFindController,
+      state: {
+        query: "o"
+      },
+      matchesPerPage: [13],
+      selectedMatch: {
+        pageIndex: 0,
+        matchIndex: 0
+      },
+      pageMatches: [[0, 10, 13, 30, 39, 41, 55, 60, 66, 84, 102, 117, 134]],
+      pageMatchesLength: [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
+    });
+  });
 });

+ 16 - 7
lib/test/unit/test_utils.js

@@ -83,21 +83,30 @@ class XRefMock {
     this.stats = new _core_utils.DocStats({
       send: () => {}
     });
-    this._newRefNum = null;
+    this._newTemporaryRefNum = null;
+    this._newPersistentRefNum = null;
     this.stream = new _stream.NullStream();
     for (const key in array) {
       const obj = array[key];
       this._map[obj.ref.toString()] = obj.data;
     }
   }
-  getNewRef() {
-    if (this._newRefNum === null) {
-      this._newRefNum = Object.keys(this._map).length || 1;
+  getNewPersistentRef(obj) {
+    if (this._newPersistentRefNum === null) {
+      this._newPersistentRefNum = Object.keys(this._map).length || 1;
     }
-    return _primitives.Ref.get(this._newRefNum++, 0);
+    const ref = _primitives.Ref.get(this._newPersistentRefNum++, 0);
+    this._map[ref.toString()] = obj;
+    return ref;
   }
-  resetNewRef() {
-    this.newRef = null;
+  getNewTemporaryRef() {
+    if (this._newTemporaryRefNum === null) {
+      this._newTemporaryRefNum = Object.keys(this._map).length || 1;
+    }
+    return _primitives.Ref.get(this._newTemporaryRefNum++, 0);
+  }
+  resetNewTemporaryRef() {
+    this._newTemporaryRefNum = null;
   }
   fetch(ref) {
     return this._map[ref.toString()];

+ 0 - 18
lib/test/unit/util_spec.js

@@ -172,28 +172,10 @@ describe("util", function () {
       }
     });
   });
-  describe("escapeString", function () {
-    it("should escape (, ), \\n, \\r, and \\", function () {
-      expect((0, _util.escapeString)("((a\\a))\n(b(b\\b)\rb)")).toEqual("\\(\\(a\\\\a\\)\\)\\n\\(b\\(b\\\\b\\)\\rb\\)");
-    });
-  });
   describe("getModificationDate", function () {
     it("should get a correctly formatted date", function () {
       const date = new Date(Date.UTC(3141, 5, 9, 2, 6, 53));
       expect((0, _util.getModificationDate)(date)).toEqual("31410609020653");
     });
   });
-  describe("isAscii", function () {
-    it("handles ascii/non-ascii strings", function () {
-      expect((0, _util.isAscii)("hello world")).toEqual(true);
-      expect((0, _util.isAscii)("こんにちは世界の")).toEqual(false);
-      expect((0, _util.isAscii)("hello world in Japanese is こんにちは世界の")).toEqual(false);
-    });
-  });
-  describe("stringToUTF16BEString", function () {
-    it("should encode a string in UTF16BE with a BOM", function () {
-      expect((0, _util.stringToUTF16BEString)("hello world")).toEqual("\xfe\xff\0h\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d");
-      expect((0, _util.stringToUTF16BEString)("こんにちは世界の")).toEqual("\xfe\xff\x30\x53\x30\x93\x30\x6b\x30\x61" + "\x30\x6f\x4e\x16\x75\x4c\x30\x6e");
-    });
-  });
 });

+ 2 - 2
lib/test/unit/writer_spec.js

@@ -104,7 +104,7 @@ describe("Writer", function () {
       dict.set("NullVal", null);
       const buffer = [];
       (0, _writer.writeDict)(dict, buffer, null);
-      const expected = "<< /A /B /B 123 456 R /C 789 /D (hello world) " + "/E (\\(hello\\\\world\\)) /F [1.23 4.5 6] " + "/G << /H 123 /I << /Length 8>> stream\n" + "a stream\n" + "endstream\n>> /J true /K false " + "/NullArr [null 10] /NullVal null>>";
+      const expected = "<< /A /B /B 123 456 R /C 789 /D (hello world) " + "/E (\\(hello\\\\world\\)) /F [1.23 4.5 6] " + "/G << /H 123 /I << /Length 8>> stream\n" + "a stream\n" + "endstream>> /J true /K false " + "/NullArr [null 10] /NullVal null>>";
       expect(buffer.join("")).toEqual(expected);
     });
     it("should write a Dict in escaping PDF names", function () {
@@ -150,7 +150,7 @@ describe("Writer", function () {
         xref: {}
       });
       data = (0, _util.bytesToString)(data);
-      const expected = "\n" + "789 0 obj\n" + "<< /XFA [(preamble) 123 0 R (datasets) 101112 0 R (postamble) 456 0 R]>>\n" + "101112 0 obj\n" + "<< /Type /EmbeddedFile /Length 20>>\n" + "stream\n" + "<hello>world</hello>\n" + "endstream\n" + "endobj\n" + "131415 0 obj\n" + "<< /Size 131416 /Prev 314 /Type /XRef /Index [0 1 789 1 101112 1 131415 1] /W [1 1 2] /Length 16>> stream\n" + "\u0000\u0001ÿÿ\u0001\u0001\u0000\u0000\u0001T\u0000\u0000\u0001²\u0000\u0000\n" + "endstream\n" + "endobj\n" + "startxref\n" + "178\n" + "%%EOF\n";
+      const expected = "\n" + "789 0 obj\n" + "<< /XFA [(preamble) 123 0 R (datasets) 101112 0 R (postamble) 456 0 R]>>\n" + "endobj\n" + "101112 0 obj\n" + "<< /Type /EmbeddedFile /Length 20>>\n" + "stream\n" + "<hello>world</hello>\n" + "endstream\n" + "endobj\n" + "131415 0 obj\n" + "<< /Size 131416 /Prev 314 /Type /XRef /Index [0 1 789 1 101112 1 131415 1] /W [1 1 2] /Length 16>> stream\n" + "\u0000\u0001ÿÿ\u0001\u0001\u0000\u0000\u0001[\u0000\u0000\u0001¹\u0000\u0000\n" + "endstream\n" + "endobj\n" + "startxref\n" + "185\n" + "%%EOF\n";
       expect(data).toEqual(expected);
     });
   });

+ 37 - 0
lib/web/annotation_layer_builder.js

@@ -27,7 +27,9 @@ Object.defineProperty(exports, "__esModule", {
 exports.AnnotationLayerBuilder = void 0;
 var _pdf = require("../pdf");
 var _l10n_utils = require("./l10n_utils.js");
+var _ui_utils = require("./ui_utils.js");
 class AnnotationLayerBuilder {
+  #onPresentationModeChanged = null;
   constructor({
     pageDiv,
     pdfPage,
@@ -60,6 +62,7 @@ class AnnotationLayerBuilder {
     this._accessibilityManager = accessibilityManager;
     this.div = null;
     this._cancelled = false;
+    this._eventBus = linkService.eventBus;
   }
   async render(viewport, intent = "display") {
     const [annotations, hasJSActions = false, fieldObjects = null] = await Promise.all([this.pdfPage.getAnnotations({
@@ -96,10 +99,23 @@ class AnnotationLayerBuilder {
       parameters.div = this.div;
       _pdf.AnnotationLayer.render(parameters);
       this.l10n.translate(this.div);
+      if (this.linkService.isInPresentationMode) {
+        this.#updatePresentationModeState(_ui_utils.PresentationModeState.FULLSCREEN);
+      }
+      if (!this.#onPresentationModeChanged) {
+        this.#onPresentationModeChanged = evt => {
+          this.#updatePresentationModeState(evt.state);
+        };
+        this._eventBus?._on("presentationmodechanged", this.#onPresentationModeChanged);
+      }
     }
   }
   cancel() {
     this._cancelled = true;
+    if (this.#onPresentationModeChanged) {
+      this._eventBus?._off("presentationmodechanged", this.#onPresentationModeChanged);
+      this.#onPresentationModeChanged = null;
+    }
   }
   hide() {
     if (!this.div) {
@@ -107,5 +123,26 @@ class AnnotationLayerBuilder {
     }
     this.div.hidden = true;
   }
+  #updatePresentationModeState(state) {
+    if (!this.div) {
+      return;
+    }
+    let disableFormElements = false;
+    switch (state) {
+      case _ui_utils.PresentationModeState.FULLSCREEN:
+        disableFormElements = true;
+        break;
+      case _ui_utils.PresentationModeState.NORMAL:
+        break;
+      default:
+        return;
+    }
+    for (const section of this.div.childNodes) {
+      if (section.hasAttribute("data-internal-link")) {
+        continue;
+      }
+      section.inert = disableFormElements;
+    }
+  }
 }
 exports.AnnotationLayerBuilder = AnnotationLayerBuilder;

+ 3 - 0
lib/web/app.js

@@ -597,6 +597,9 @@ const PDFViewerApplication = {
     const loadingTask = (0, _pdf.getDocument)(parameters);
     this.pdfLoadingTask = loadingTask;
     loadingTask.onPassword = (updateCallback, reason) => {
+      if (this.isViewerEmbedded) {
+        this._unblockDocumentLoadEvent();
+      }
       this.pdfLinkService.externalLinkEnabled = false;
       this.passwordPrompt.setUpdateCallback(updateCallback, reason);
       this.passwordPrompt.open();

+ 4 - 6
lib/web/download_manager.js

@@ -42,9 +42,7 @@ function download(blobUrl, filename) {
   a.remove();
 }
 class DownloadManager {
-  constructor() {
-    this._openBlobUrls = new WeakMap();
-  }
+  #openBlobUrls = new WeakMap();
   downloadUrl(url, filename) {
     if (!(0, _pdf.createValidAbsoluteUrl)(url, "http://example.com")) {
       console.error(`downloadUrl - not a valid URL: ${url}`);
@@ -62,12 +60,12 @@ class DownloadManager {
     const isPdfData = (0, _pdf.isPdfFile)(filename);
     const contentType = isPdfData ? "application/pdf" : "";
     if (isPdfData) {
-      let blobUrl = this._openBlobUrls.get(element);
+      let blobUrl = this.#openBlobUrls.get(element);
       if (!blobUrl) {
         blobUrl = URL.createObjectURL(new Blob([data], {
           type: contentType
         }));
-        this._openBlobUrls.set(element, blobUrl);
+        this.#openBlobUrls.set(element, blobUrl);
       }
       let viewerUrl;
       viewerUrl = "?file=" + encodeURIComponent(blobUrl + "#" + filename);
@@ -77,7 +75,7 @@ class DownloadManager {
       } catch (ex) {
         console.error(`openOrDownloadData: ${ex}`);
         URL.revokeObjectURL(blobUrl);
-        this._openBlobUrls.delete(element);
+        this.#openBlobUrls.delete(element);
       }
     }
     this.downloadData(data, filename, contentType);

+ 4 - 6
lib/web/event_utils.js

@@ -62,9 +62,7 @@ function waitOnEventOrTimeout({
   });
 }
 class EventBus {
-  constructor() {
-    this._listeners = Object.create(null);
-  }
+  #listeners = Object.create(null);
   on(eventName, listener, options = null) {
     this._on(eventName, listener, {
       external: true,
@@ -78,7 +76,7 @@ class EventBus {
     });
   }
   dispatch(eventName, data) {
-    const eventListeners = this._listeners[eventName];
+    const eventListeners = this.#listeners[eventName];
     if (!eventListeners || eventListeners.length === 0) {
       return;
     }
@@ -105,7 +103,7 @@ class EventBus {
     }
   }
   _on(eventName, listener, options = null) {
-    const eventListeners = this._listeners[eventName] ||= [];
+    const eventListeners = this.#listeners[eventName] ||= [];
     eventListeners.push({
       listener,
       external: options?.external === true,
@@ -113,7 +111,7 @@ class EventBus {
     });
   }
   _off(eventName, listener, options = null) {
-    const eventListeners = this._listeners[eventName];
+    const eventListeners = this.#listeners[eventName];
     if (!eventListeners) {
       return;
     }

+ 4 - 6
lib/web/firefoxcom.js

@@ -78,9 +78,7 @@ class FirefoxCom {
 }
 exports.FirefoxCom = FirefoxCom;
 class DownloadManager {
-  constructor() {
-    this._openBlobUrls = new WeakMap();
-  }
+  #openBlobUrls = new WeakMap();
   downloadUrl(url, filename) {
     FirefoxCom.request("download", {
       originalUrl: url,
@@ -102,12 +100,12 @@ class DownloadManager {
     const isPdfData = (0, _pdf.isPdfFile)(filename);
     const contentType = isPdfData ? "application/pdf" : "";
     if (isPdfData) {
-      let blobUrl = this._openBlobUrls.get(element);
+      let blobUrl = this.#openBlobUrls.get(element);
       if (!blobUrl) {
         blobUrl = URL.createObjectURL(new Blob([data], {
           type: contentType
         }));
-        this._openBlobUrls.set(element, blobUrl);
+        this.#openBlobUrls.set(element, blobUrl);
       }
       const viewerUrl = blobUrl + "#filename=" + encodeURIComponent(filename);
       try {
@@ -116,7 +114,7 @@ class DownloadManager {
       } catch (ex) {
         console.error(`openOrDownloadData: ${ex}`);
         URL.revokeObjectURL(blobUrl);
-        this._openBlobUrls.delete(element);
+        this.#openBlobUrls.delete(element);
       }
     }
     this.downloadData(data, filename, contentType);

+ 1 - 0
lib/web/interfaces.js

@@ -31,6 +31,7 @@ class IPDFLinkService {
   set page(value) {}
   get rotation() {}
   set rotation(value) {}
+  get isInPresentationMode() {}
   get externalLinkEnabled() {}
   set externalLinkEnabled(value) {}
   async goToDestination(dest) {}

+ 1 - 1
lib/web/pdf_attachment_viewer.js

@@ -90,7 +90,7 @@ class PDFAttachmentViewer extends _base_tree_viewer.BaseTreeViewer {
     for (const name of names) {
       const item = attachments[name];
       const content = item.content,
-        filename = (0, _pdf.getFilenameFromUrl)(item.filename);
+        filename = (0, _pdf.getFilenameFromUrl)(item.filename, true);
       const div = document.createElement("div");
       div.className = "treeItem";
       const element = document.createElement("a");

+ 30 - 14
lib/web/pdf_find_controller.js

@@ -53,7 +53,7 @@ const CHARACTERS_TO_NORMALIZE = {
   "\u00BE": "3/4"
 };
 const DIACRITICS_EXCEPTION = new Set([0x3099, 0x309a, 0x094d, 0x09cd, 0x0a4d, 0x0acd, 0x0b4d, 0x0bcd, 0x0c4d, 0x0ccd, 0x0d3b, 0x0d3c, 0x0d4d, 0x0dca, 0x0e3a, 0x0eba, 0x0f84, 0x1039, 0x103a, 0x1714, 0x1734, 0x17d2, 0x1a60, 0x1b44, 0x1baa, 0x1bab, 0x1bf2, 0x1bf3, 0x2d7f, 0xa806, 0xa82c, 0xa8c4, 0xa953, 0xa9c0, 0xaaf6, 0xabed, 0x0c56, 0x0f71, 0x0f72, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f80, 0x0f74]);
-const DIACRITICS_EXCEPTION_STR = [...DIACRITICS_EXCEPTION.values()].map(x => String.fromCharCode(x)).join("");
+let DIACRITICS_EXCEPTION_STR;
 const DIACRITICS_REG_EXP = /\p{M}+/gu;
 const SPECIAL_CHARS_REG_EXP = /([.*+?^${}()|[\]\\])|(\p{P})|(\s+)|(\p{M})|(\p{L})/gu;
 const NOT_DIACRITIC_FROM_END_REG_EXP = /([^\p{M}])\p{M}*$/u;
@@ -61,6 +61,7 @@ const NOT_DIACRITIC_FROM_START_REG_EXP = /^\p{M}*([^\p{M}])/u;
 const SYLLABLES_REG_EXP = /[\uAC00-\uD7AF\uFA6C\uFACF-\uFAD1\uFAD5-\uFAD7]+/g;
 const SYLLABLES_LENGTHS = new Map();
 const FIRST_CHAR_SYLLABLES_REG_EXP = "[\\u1100-\\u1112\\ud7a4-\\ud7af\\ud84a\\ud84c\\ud850\\ud854\\ud857\\ud85f]";
+const NFKC_CHARS_TO_NORMALIZE = new Map();
 let noSyllablesRegExp = null;
 let withSyllablesRegExp = null;
 function normalize(text) {
@@ -86,7 +87,8 @@ function normalize(text) {
     normalizationRegex = withSyllablesRegExp;
   } else {
     const replace = Object.keys(CHARACTERS_TO_NORMALIZE).join("");
-    const regexp = `([${replace}])|(\\p{M}+(?:-\\n)?)|(\\S-\\n)|(\\p{Ideographic}\\n)|(\\n)`;
+    const toNormalizeWithNFKC = "\u2460-\u2473" + "\u24b6-\u24ff" + "\u3244-\u32bf" + "\u32d0-\u32fe" + "\uff00-\uffef";
+    const regexp = `([${replace}])|([${toNormalizeWithNFKC}])|(\\p{M}+(?:-\\n)?)|(\\S-\\n)|(\\p{Ideographic}\\n)|(\\n)`;
     if (syllablePositions.length === 0) {
       normalizationRegex = noSyllablesRegExp = new RegExp(regexp + "|(\\u0000)", "gum");
     } else {
@@ -105,10 +107,10 @@ function normalize(text) {
   let shiftOrigin = 0;
   let eol = 0;
   let hasDiacritics = false;
-  normalized = normalized.replace(normalizationRegex, (match, p1, p2, p3, p4, p5, p6, i) => {
+  normalized = normalized.replace(normalizationRegex, (match, p1, p2, p3, p4, p5, p6, p7, i) => {
     i -= shiftOrigin;
     if (p1) {
-      const replacement = CHARACTERS_TO_NORMALIZE[match];
+      const replacement = CHARACTERS_TO_NORMALIZE[p1];
       const jj = replacement.length;
       for (let j = 1; j < jj; j++) {
         positions.push([i - shift + j, shift - j]);
@@ -117,8 +119,21 @@ function normalize(text) {
       return replacement;
     }
     if (p2) {
-      const hasTrailingDashEOL = p2.endsWith("\n");
-      const len = hasTrailingDashEOL ? p2.length - 2 : p2.length;
+      let replacement = NFKC_CHARS_TO_NORMALIZE.get(p2);
+      if (!replacement) {
+        replacement = p2.normalize("NFKC");
+        NFKC_CHARS_TO_NORMALIZE.set(p2, replacement);
+      }
+      const jj = replacement.length;
+      for (let j = 1; j < jj; j++) {
+        positions.push([i - shift + j, shift - j]);
+      }
+      shift -= jj - 1;
+      return replacement;
+    }
+    if (p3) {
+      const hasTrailingDashEOL = p3.endsWith("\n");
+      const len = hasTrailingDashEOL ? p3.length - 2 : p3.length;
       hasDiacritics = true;
       let jj = len;
       if (i + eol === rawDiacriticsPositions[rawDiacriticsIndex]?.[1]) {
@@ -136,24 +151,24 @@ function normalize(text) {
         shift += 1;
         shiftOrigin += 1;
         eol += 1;
-        return p2.slice(0, len);
+        return p3.slice(0, len);
       }
-      return p2;
+      return p3;
     }
-    if (p3) {
+    if (p4) {
       positions.push([i - shift + 1, 1 + shift]);
       shift += 1;
       shiftOrigin += 1;
       eol += 1;
-      return p3.charAt(0);
+      return p4.charAt(0);
     }
-    if (p4) {
+    if (p5) {
       positions.push([i - shift + 1, shift]);
       shiftOrigin += 1;
       eol += 1;
-      return p4.charAt(0);
+      return p5.charAt(0);
     }
-    if (p5) {
+    if (p6) {
       positions.push([i - shift + 1, shift - 1]);
       shift -= 1;
       shiftOrigin += 1;
@@ -169,7 +184,7 @@ function normalize(text) {
       shift -= newCharLen;
       shiftOrigin += newCharLen;
     }
-    return p6;
+    return p7;
   });
   positions.push([normalized.length, shift]);
   return [normalized, positions, hasDiacritics];
@@ -419,6 +434,7 @@ class PDFFindController {
     }
     if (matchDiacritics) {
       if (hasDiacritics) {
+        DIACRITICS_EXCEPTION_STR ||= String.fromCharCode(...DIACRITICS_EXCEPTION);
         isUnicode = true;
         query = `${query}(?=[${DIACRITICS_EXCEPTION_STR}]|[^\\p{M}]|$)`;
       }

+ 6 - 0
lib/web/pdf_link_service.js

@@ -118,6 +118,9 @@ class PDFLinkService {
   set rotation(value) {
     this.pdfViewer.pagesRotation = value;
   }
+  get isInPresentationMode() {
+    return this.pdfViewer.isInPresentationMode;
+  }
   #goToDestinationHelper(rawDest, namedDest = null, explicitDest) {
     const destRef = explicitDest[0];
     let pageNumber;
@@ -443,6 +446,9 @@ class SimpleLinkService {
     return 0;
   }
   set rotation(value) {}
+  get isInPresentationMode() {
+    return false;
+  }
   async goToDestination(dest) {}
   goToPage(val) {}
   addLinkAttributes(link, url, newWindow = false) {

+ 11 - 10
lib/web/pdf_presentation_mode.js

@@ -166,16 +166,17 @@ class PDFPresentationMode {
       evt.preventDefault();
       return;
     }
-    if (evt.button === 0) {
-      const isInternalLink = evt.target.href && evt.target.classList.contains("internalLink");
-      if (!isInternalLink) {
-        evt.preventDefault();
-        if (evt.shiftKey) {
-          this.pdfViewer.previousPage();
-        } else {
-          this.pdfViewer.nextPage();
-        }
-      }
+    if (evt.button !== 0) {
+      return;
+    }
+    if (evt.target.href && evt.target.parentNode?.hasAttribute("data-internal-link")) {
+      return;
+    }
+    evt.preventDefault();
+    if (evt.shiftKey) {
+      this.pdfViewer.previousPage();
+    } else {
+      this.pdfViewer.nextPage();
     }
   }
   #contextMenu() {

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

@@ -197,5 +197,5 @@ var _pdf_viewer = require("./pdf_viewer.js");
 var _struct_tree_layer_builder = require("./struct_tree_layer_builder.js");
 var _text_layer_builder = require("./text_layer_builder.js");
 var _xfa_layer_builder = require("./xfa_layer_builder.js");
-const pdfjsVersion = '3.0.279';
-const pdfjsBuild = 'd0823066c';
+const pdfjsVersion = '3.1.81';
+const pdfjsBuild = '0766898d5';

+ 7 - 2
lib/web/pdf_viewer.js

@@ -107,7 +107,7 @@ class PDFViewer {
   #scrollModePageState = null;
   #onVisibilityChange = null;
   constructor(options) {
-    const viewerVersion = '3.0.279';
+    const viewerVersion = '3.1.81';
     if (_pdf.version !== viewerVersion) {
       throw new Error(`The API version "${_pdf.version}" does not match the Viewer version "${viewerVersion}".`);
     }
@@ -636,8 +636,10 @@ class PDFViewer {
       div,
       id
     } = pageView;
-    if (this._scrollMode === _ui_utils.ScrollMode.PAGE) {
+    if (this._currentPageNumber !== id) {
       this._setCurrentPageNumber(id);
+    }
+    if (this._scrollMode === _ui_utils.ScrollMode.PAGE) {
       this.#ensurePageViewVisible();
       this.update();
     }
@@ -656,6 +658,9 @@ class PDFViewer {
       }
     }
     (0, _ui_utils.scrollIntoView)(div, pageSpot);
+    if (!this._currentScaleValue && this._location) {
+      this._location = null;
+    }
   }
   #isSameScale(newScale) {
     return newScale === this._currentScale || Math.abs(newScale - this._currentScale) < 1e-15;

+ 4 - 2
package.json

@@ -1,6 +1,6 @@
 {
   "name": "pdfjs-dist",
-  "version": "3.0.279",
+  "version": "3.1.81",
   "main": "build/pdf.js",
   "types": "types/src/pdf.d.ts",
   "description": "Generic build of Mozilla's PDF.js library.",
@@ -12,8 +12,10 @@
   "homepage": "http://mozilla.github.io/pdf.js/",
   "bugs": "https://github.com/mozilla/pdf.js/issues",
   "license": "Apache-2.0",
+  "optionalDependencies": {
+    "canvas": "^2.10.2"
+  },
   "dependencies": {
-    "canvas": "^2.10.1",
     "web-streams-polyfill": "^3.2.1"
   },
   "browser": {

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

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

+ 3 - 14
types/src/display/annotation_storage.d.ts

@@ -7,30 +7,22 @@ export class AnnotationStorage {
      * @ignore
      */
     static getHash(map: any): string;
-    _storage: Map<any, any>;
-    _modified: boolean;
     onSetModified: any;
     onResetModified: any;
     onAnnotationEditor: any;
     /**
      * Get the value for a given key if it exists, or return the default value.
-     *
-     * @public
-     * @memberof AnnotationStorage
      * @param {string} key
      * @param {Object} defaultValue
      * @returns {Object}
      */
-    public getValue(key: string, defaultValue: Object): Object;
+    getValue(key: string, defaultValue: Object): Object;
     /**
      * Get the value for a given key.
-     *
-     * @public
-     * @memberof AnnotationStorage
      * @param {string} key
      * @returns {Object}
      */
-    public getRawValue(key: string): Object;
+    getRawValue(key: string): Object;
     /**
      * Remove a value from the storage.
      * @param {string} key
@@ -38,13 +30,10 @@ export class AnnotationStorage {
     remove(key: string): void;
     /**
      * Set the value for a given key
-     *
-     * @public
-     * @memberof AnnotationStorage
      * @param {string} key
      * @param {Object} value
      */
-    public setValue(key: string, value: Object): void;
+    setValue(key: string, value: Object): void;
     /**
      * Check if the storage contains the given key.
      * @param {string} key

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

@@ -1,5 +1,8 @@
 export class CanvasGraphics {
-    constructor(canvasCtx: any, commonObjs: any, objs: any, canvasFactory: any, optionalContentConfig: any, annotationCanvasMap: any, pageColors: any);
+    constructor(canvasCtx: any, commonObjs: any, objs: any, canvasFactory: any, { optionalContentConfig, markedContentStack }: {
+        optionalContentConfig: any;
+        markedContentStack?: null | undefined;
+    }, annotationCanvasMap: any, pageColors: any);
     ctx: any;
     current: CanvasExtraState;
     stateStack: any[];
@@ -20,7 +23,7 @@ export class CanvasGraphics {
     tempSMask: any;
     suspendedCtx: any;
     contentVisible: boolean;
-    markedContentStack: any[];
+    markedContentStack: never[];
     optionalContentConfig: any;
     cachedCanvases: CachedCanvases;
     cachedPatterns: Map<any, any>;

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

@@ -94,9 +94,10 @@ export function getCurrentTransformInverse(ctx: any): any[];
 /**
  * Gets the filename from a given URL.
  * @param {string} url
+ * @param {boolean} [onlyStripPath]
  * @returns {string}
  */
-export function getFilenameFromUrl(url: string): string;
+export function getFilenameFromUrl(url: string, onlyStripPath?: boolean | undefined): string;
 /**
  * Returns the filename or guessed filename from the url (see issue 3455).
  * @param {string} url - The original PDF location.

+ 0 - 1
types/src/display/text_layer.d.ts

@@ -71,7 +71,6 @@ export class TextLayerRenderTask {
     _canceled: boolean;
     _capability: import("../shared/util.js").PromiseCapability;
     _renderTimer: any;
-    _bounds: any[];
     _devicePixelRatio: number;
     /**
      * Promise for textLayer rendering task completion.

+ 3 - 4
types/src/shared/util.d.ts

@@ -176,6 +176,7 @@ export function assert(cond: any, msg: any): void;
  * @type {any}
  */
 export const BaseException: any;
+export const BASELINE_FACTOR: number;
 export function bytesToString(bytes: any): string;
 export namespace CMapCompressionType {
     const NONE_2: number;
@@ -214,7 +215,6 @@ export namespace DocumentActionEventType {
     const WP: string;
     const DP: string;
 }
-export function escapeString(str: any): any;
 export class FeatureTest {
     static get isLittleEndian(): any;
     static get isEvalSupported(): any;
@@ -259,7 +259,6 @@ export class InvalidPDFException extends InvalidPDFException_base {
 }
 export function isArrayBuffer(v: any): boolean;
 export function isArrayEqual(arr1: any, arr2: any): boolean;
-export function isAscii(str: any): boolean;
 export const LINE_DESCENT_FACTOR: 0.35;
 export const LINE_FACTOR: 1.35;
 declare const MissingPDFException_base: any;
@@ -390,13 +389,14 @@ export namespace RenderingIntentFlag {
     export const DISPLAY: number;
     const PRINT_2: number;
     export { PRINT_2 as PRINT };
+    export const SAVE: number;
     export const ANNOTATIONS_FORMS: number;
     export const ANNOTATIONS_STORAGE: number;
     export const ANNOTATIONS_DISABLE: number;
     export const OPLIST: number;
 }
 export function setVerbosityLevel(level: any): void;
-export function shadow(obj: any, prop: any, value: any): any;
+export function shadow(obj: any, prop: any, value: any, nonSerializable?: boolean): any;
 export namespace StreamType {
     const UNKNOWN_1: string;
     export { UNKNOWN_1 as UNKNOWN };
@@ -413,7 +413,6 @@ export namespace StreamType {
 export function string32(value: any): string;
 export function stringToBytes(str: any): Uint8Array;
 export function stringToPDFString(str: any): string;
-export function stringToUTF16BEString(str: any): string;
 export function stringToUTF8String(str: any): string;
 export namespace TextRenderingMode {
     export const FILL: number;

+ 2 - 0
types/web/annotation_layer_builder.d.ts

@@ -71,6 +71,7 @@ export class AnnotationLayerBuilder {
     _accessibilityManager: any;
     div: HTMLDivElement | null;
     _cancelled: boolean;
+    _eventBus: any;
     /**
      * @param {PageViewport} viewport
      * @param {string} intent (default value is 'display')
@@ -80,4 +81,5 @@ export class AnnotationLayerBuilder {
     render(viewport: PageViewport, intent?: string): Promise<void>;
     cancel(): void;
     hide(): void;
+    #private;
 }

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

@@ -3,7 +3,6 @@ export type IDownloadManager = import("./interfaces").IDownloadManager;
  * @implements {IDownloadManager}
  */
 export class DownloadManager implements IDownloadManager {
-    _openBlobUrls: WeakMap<object, any>;
     downloadUrl(url: any, filename: any): void;
     downloadData(data: any, filename: any, contentType: any): void;
     /**
@@ -11,4 +10,5 @@ export class DownloadManager implements IDownloadManager {
      */
     openOrDownloadData(element: any, data: any, filename: any): boolean;
     download(blob: any, url: any, filename: any): void;
+    #private;
 }

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

@@ -25,7 +25,6 @@ export class AutomationEventBus extends EventBus {
  * and `off` methods. To raise an event, the `dispatch` method shall be used.
  */
 export class EventBus {
-    _listeners: any;
     /**
      * @param {string} eventName
      * @param {function} listener
@@ -51,6 +50,7 @@ export class EventBus {
      * @ignore
      */
     _off(eventName: any, listener: any, options?: null): void;
+    #private;
 }
 /**
  * @typedef {Object} WaitOnEventOrTimeoutParameters

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

@@ -191,6 +191,10 @@ export class IPDFLinkService {
      * @type {number}
      */
     get rotation(): number;
+    /**
+     * @type {boolean}
+     */
+    get isInPresentationMode(): boolean;
     /**
      * @param {boolean} value
      */

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

@@ -75,7 +75,7 @@ export namespace LinkTarget {
  * @implements {IPDFLinkService}
  */
 export class PDFLinkService implements IPDFLinkService {
-    static "__#29@#isValidExplicitDestination"(dest: any): boolean;
+    static "__#31@#isValidExplicitDestination"(dest: any): boolean;
     /**
      * @param {PDFLinkServiceOptions} options
      */
@@ -112,6 +112,10 @@ export class PDFLinkService implements IPDFLinkService {
      * @type {number}
      */
     get rotation(): number;
+    /**
+     * @type {boolean}
+     */
+    get isInPresentationMode(): boolean;
     /**
      * This method will, when available, also update the browser history.
      *
@@ -199,6 +203,10 @@ export class SimpleLinkService implements IPDFLinkService {
      * @type {number}
      */
     get rotation(): number;
+    /**
+     * @type {boolean}
+     */
+    get isInPresentationMode(): boolean;
     /**
      * @param {string|Array} dest - The named, or explicit, PDF destination.
      */

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

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

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

@@ -14,7 +14,7 @@ export class TextAccessibilityManager {
      * @param {HTMLElement} e2
      * @returns {number}
      */
-    static "__#23@#compareElementPositions"(e1: HTMLElement, e2: HTMLElement): number;
+    static "__#24@#compareElementPositions"(e1: HTMLElement, e2: HTMLElement): number;
     setTextMapping(textDivs: any): void;
     /**
      * Function called when the text layer has finished rendering.

Разлика између датотеке није приказан због своје велике величине
+ 904 - 861
web/pdf_viewer.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
web/pdf_viewer.js.map


Неке датотеке нису приказане због велике количине промена