text: /**
   * @licstart The following is the entire license notice for the
   * JavaScript code in this page
   *
   * Copyright 2022 Mozilla Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   *
   * @licend The above is the entire license notice for the
   * JavaScript code in this page
   */
  "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.FontLoader = exports.FontFaceObject = void 0;
  
  var _util = require("../shared/util.js");
  
  class BaseFontLoader {
    constructor({
      docId,
      onUnsupportedFeature,
      ownerDocument = globalThis.document,
      styleElement = null
    }) {
      if (this.constructor === BaseFontLoader) {
        (0, _util.unreachable)("Cannot initialize BaseFontLoader.");
      }
  
      this.docId = docId;
      this._onUnsupportedFeature = onUnsupportedFeature;
      this._document = ownerDocument;
      this.nativeFontFaces = [];
      this.styleElement = null;
    }
  
    addNativeFontFace(nativeFontFace) {
      this.nativeFontFaces.push(nativeFontFace);
  
      this._document.fonts.add(nativeFontFace);
    }
  
    insertRule(rule) {
      let styleElement = this.styleElement;
  
      if (!styleElement) {
        styleElement = this.styleElement = this._document.createElement("style");
        styleElement.id = `PDFJS_FONT_STYLE_TAG_${this.docId}`;
  
        this._document.documentElement.getElementsByTagName("head")[0].appendChild(styleElement);
      }
  
      const styleSheet = styleElement.sheet;
      styleSheet.insertRule(rule, styleSheet.cssRules.length);
    }
  
    clear() {
      for (const nativeFontFace of this.nativeFontFaces) {
        this._document.fonts.delete(nativeFontFace);
      }
  
      this.nativeFontFaces.length = 0;
  
      if (this.styleElement) {
        this.styleElement.remove();
        this.styleElement = null;
      }
    }
  
    async bind(font) {
      if (font.attached || font.missingFile) {
        return;
      }
  
      font.attached = true;
  
      if (this.isFontLoadingAPISupported) {
        const nativeFontFace = font.createNativeFontFace();
  
        if (nativeFontFace) {
          this.addNativeFontFace(nativeFontFace);
  
          try {
            await nativeFontFace.loaded;
          } catch (ex) {
            this._onUnsupportedFeature({
              featureId: _util.UNSUPPORTED_FEATURES.errorFontLoadNative
            });
  
            (0, _util.warn)(`Failed to load font '${nativeFontFace.family}': '${ex}'.`);
            font.disableFontFace = true;
            throw ex;
          }
        }
  
        return;
      }
  
      const rule = font.createFontFaceRule();
  
      if (rule) {
        this.insertRule(rule);
  
        if (this.isSyncFontLoadingSupported) {
          return;
        }
  
        await new Promise(resolve => {
          const request = this._queueLoadingCallback(resolve);
  
          this._prepareFontLoadEvent([rule], [font], request);
        });
      }
    }
  
    _queueLoadingCallback(callback) {
      (0, _util.unreachable)("Abstract method `_queueLoadingCallback`.");
    }
  
    get isFontLoadingAPISupported() {
      const hasFonts = !!this._document?.fonts;
      return (0, _util.shadow)(this, "isFontLoadingAPISupported", hasFonts);
    }
  
    get isSyncFontLoadingSupported() {
      (0, _util.unreachable)("Abstract method `isSyncFontLoadingSupported`.");
    }
  
    get _loadTestFont() {
      (0, _util.unreachable)("Abstract method `_loadTestFont`.");
    }
  
    _prepareFontLoadEvent(rules, fontsToLoad, request) {
      (0, _util.unreachable)("Abstract method `_prepareFontLoadEvent`.");
    }
  
  }
  
  let FontLoader;
  exports.FontLoader = FontLoader;
  {
    exports.FontLoader = FontLoader = class GenericFontLoader extends BaseFontLoader {
      constructor(params) {
        super(params);
        this.loadingContext = {
          requests: [],
          nextRequestId: 0
        };
        this.loadTestFontId = 0;
      }
  
      get isSyncFontLoadingSupported() {
        let supported = false;
  
        if (typeof navigator === "undefined") {
          supported = true;
        } else {
          const m = /Mozilla\/5.0.*?rv:(\d+).*? Gecko/.exec(navigator.userAgent);
  
          if (m?.[1] >= 14) {
            supported = true;
          }
        }
  
        return (0, _util.shadow)(this, "isSyncFontLoadingSupported", supported);
      }
  
      _queueLoadingCallback(callback) {
        function completeRequest() {
          (0, _util.assert)(!request.done, "completeRequest() cannot be called twice.");
          request.done = true;
  
          while (context.requests.length > 0 && context.requests[0].done) {
            const otherRequest = context.requests.shift();
            setTimeout(otherRequest.callback, 0);
          }
        }
  
        const context = this.loadingContext;
        const request = {
          id: `pdfjs-font-loading-${context.nextRequestId++}`,
          done: false,
          complete: completeRequest,
          callback
        };
        context.requests.push(request);
        return request;
      }
  
      get _loadTestFont() {
        const getLoadTestFont = function () {
          return atob("T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQA" + "FQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAA" + "ALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgA" + "AAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1" + "AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD" + "6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACM" + "AooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4D" + "IP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAA" + "AAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUA" + "AQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgAB" + "AAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABY" + "AAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAA" + "AC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAA" + "AAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQAC" + "AQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3" + "Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTj" + "FQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA==");
        };
  
        return (0, _util.shadow)(this, "_loadTestFont", getLoadTestFont());
      }
  
      _prepareFontLoadEvent(rules, fonts, request) {
        function int32(data, offset) {
          return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff;
        }
  
        function spliceString(s, offset, remove, insert) {
          const chunk1 = s.substring(0, offset);
          const chunk2 = s.substring(offset + remove);
          return chunk1 + insert + chunk2;
        }
  
        let i, ii;
  
        const canvas = this._document.createElement("canvas");
  
        canvas.width = 1;
        canvas.height = 1;
        const ctx = canvas.getContext("2d");
        let called = 0;
  
        function isFontReady(name, callback) {
          called++;
  
          if (called > 30) {
            (0, _util.warn)("Load test font never loaded.");
            callback();
            return;
          }
  
          ctx.font = "30px " + name;
          ctx.fillText(".", 0, 20);
          const imageData = ctx.getImageData(0, 0, 1, 1);
  
          if (imageData.data[3] > 0) {
            callback();
            return;
          }
  
          setTimeout(isFontReady.bind(null, name, callback));
        }
  
        const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`;
        let data = this._loadTestFont;
        const COMMENT_OFFSET = 976;
        data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId);
        const CFF_CHECKSUM_OFFSET = 16;
        const XXXX_VALUE = 0x58585858;
        let checksum = int32(data, CFF_CHECKSUM_OFFSET);
  
        for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) {
          checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0;
        }
  
        if (i < loadTestFontId.length) {
          checksum = checksum - XXXX_VALUE + int32(loadTestFontId + "XXX", i) | 0;
        }
  
        data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, (0, _util.string32)(checksum));
        const url = `url(data:font/opentype;base64,${btoa(data)});`;
        const rule = `@font-face {font-family:"${loadTestFontId}";src:${url}}`;
        this.insertRule(rule);
        const names = [];
  
        for (const font of fonts) {
          names.push(font.loadedName);
        }
  
        names.push(loadTestFontId);
  
        const div = this._document.createElement("div");
  
        div.style.visibility = "hidden";
        div.style.width = div.style.height = "10px";
        div.style.position = "absolute";
        div.style.top = div.style.left = "0px";
  
        for (const name of names) {
          const span = this._document.createElement("span");
  
          span.textContent = "Hi";
          span.style.fontFamily = name;
          div.appendChild(span);
        }
  
        this._document.body.appendChild(div);
  
        isFontReady(loadTestFontId, () => {
          div.remove();
          request.complete();
        });
      }
  
    };
  }
  
  class FontFaceObject {
    constructor(translatedData, {
      isEvalSupported = true,
      disableFontFace = false,
      ignoreErrors = false,
      onUnsupportedFeature,
      fontRegistry = null
    }) {
      this.compiledGlyphs = Object.create(null);
  
      for (const i in translatedData) {
        this[i] = translatedData[i];
      }
  
      this.isEvalSupported = isEvalSupported !== false;
      this.disableFontFace = disableFontFace === true;
      this.ignoreErrors = ignoreErrors === true;
      this._onUnsupportedFeature = onUnsupportedFeature;
      this.fontRegistry = fontRegistry;
    }
  
    createNativeFontFace() {
      if (!this.data || this.disableFontFace) {
        return null;
      }
  
      let nativeFontFace;
  
      if (!this.cssFontInfo) {
        nativeFontFace = new FontFace(this.loadedName, this.data, {});
      } else {
        const css = {
          weight: this.cssFontInfo.fontWeight
        };
  
        if (this.cssFontInfo.italicAngle) {
          css.style = `oblique ${this.cssFontInfo.italicAngle}deg`;
        }
  
        nativeFontFace = new FontFace(this.cssFontInfo.fontFamily, this.data, css);
      }
  
      if (this.fontRegistry) {
        this.fontRegistry.registerFont(this);
      }
  
      return nativeFontFace;
    }
  
    createFontFaceRule() {
      if (!this.data || this.disableFontFace) {
        return null;
      }
  
      const data = (0, _util.bytesToString)(this.data);
      const url = `url(data:${this.mimetype};base64,${btoa(data)});`;
      let rule;
  
      if (!this.cssFontInfo) {
        rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`;
      } else {
        let css = `font-weight: ${this.cssFontInfo.fontWeight};`;
  
        if (this.cssFontInfo.italicAngle) {
          css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`;
        }
  
        rule = `@font-face {font-family:"${this.cssFontInfo.fontFamily}";${css}src:${url}}`;
      }
  
      if (this.fontRegistry) {
        this.fontRegistry.registerFont(this, url);
      }
  
      return rule;
    }
  
    getPathGenerator(objs, character) {
      if (this.compiledGlyphs[character] !== undefined) {
        return this.compiledGlyphs[character];
      }
  
      let cmds;
  
      try {
        cmds = objs.get(this.loadedName + "_path_" + character);
      } catch (ex) {
        if (!this.ignoreErrors) {
          throw ex;
        }
  
        this._onUnsupportedFeature({
          featureId: _util.UNSUPPORTED_FEATURES.errorFontGetPath
        });
  
        (0, _util.warn)(`getPathGenerator - ignoring character: "${ex}".`);
        return this.compiledGlyphs[character] = function (c, size) {};
      }
  
      if (this.isEvalSupported && _util.FeatureTest.isEvalSupported) {
        const jsBuf = [];
  
        for (const current of cmds) {
          const args = current.args !== undefined ? current.args.join(",") : "";
          jsBuf.push("c.", current.cmd, "(", args, ");\n");
        }
  
        return this.compiledGlyphs[character] = new Function("c", "size", jsBuf.join(""));
      }
  
      return this.compiledGlyphs[character] = function (c, size) {
        for (const current of cmds) {
          if (current.cmd === "scale") {
            current.args = [size, -size];
          }
  
          c[current.cmd].apply(c, current.args);
        }
      };
    }
  
  }
  
  exports.FontFaceObject = FontFaceObject;