text: /**
   * @licstart The following is the entire license notice for the
   * Javascript code in this page
   *
   * Copyright 2020 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.renderTextLayer = void 0;
  
  var _util_metapdf = require("../shared/util_metapdf.js");
  
  var renderTextLayer = function renderTextLayerClosure() {
    var MAX_TEXT_DIVS_TO_RENDER = 100000;
    var NonWhitespaceRegexp = /\S/;
    var lastFontUsed;
    var lastTop;
    var lastHeight;
  
    function isAllWhitespace(str) {
      return !NonWhitespaceRegexp.test(str);
    }
  
    function appendText(task, geom, styles) {
      var textDiv = document.createElement("span");
      var textDivProperties = {
        angle: 0,
        canvasWidth: 0,
        isWhitespace: false,
        originalTransform: null,
        paddingBottom: 0,
        paddingLeft: 0,
        paddingRight: 0,
        paddingTop: 0,
        scale: 1
      };
  
      task._textDivs.push(textDiv);
  
      if (isAllWhitespace(geom.str)) {
        textDivProperties.isWhitespace = true;
  
        task._textDivProperties.set(textDiv, textDivProperties);
  
        return;
      }
  
      var tx = _util_metapdf.Util.transform(task._viewport.transform, geom.transform);
  
      var angle = Math.atan2(tx[1], tx[0]);
      var style = styles[geom.fontName];
  
      if (style.vertical) {
        angle += Math.PI / 2;
      }
  
      var fontHeight = Math.sqrt(tx[2] * tx[2] + tx[3] * tx[3]);
      var fontAscent = fontHeight;
  
      if (style.ascent) {
        fontAscent = style.ascent * fontAscent;
      } else if (style.descent) {
        fontAscent = (1 + style.descent) * fontAscent;
      }
  
      var left, top;
  
      if (angle === 0) {
        left = tx[4];
        top = tx[5] - fontAscent;
      } else {
        left = tx[4] + fontAscent * Math.sin(angle);
        top = tx[5] - fontAscent * Math.cos(angle);
      }
  
      textDiv.style.left = "".concat(left, "px");
      textDiv.style.top = "".concat(top, "px");
      var divHeight;
  
      function giveLogPos(position) {
        var minp = 1.1;
        var maxp = 3.24;
        var minv = Math.log(geom.height - 3);
        var maxv = Math.log(geom.height + 12);
        var scale = (maxv - minv) / (maxp - minp);
        return Math.exp(minv + scale * (position - minp));
      }
  
      var displaced = false;
      var calculatedHeight;
  
      if (Math.abs(geom.transform[3] - geom.transform[0]) > 2) {
        displaced = true;
      }
  
      if (displaced) {
        calculatedHeight = Math.min(fontHeight, giveLogPos(task._viewport.transform[0]));
      } else {
        calculatedHeight = fontHeight;
      }
  
      textDiv.style.fontSize = "".concat(calculatedHeight, "px");
  
      if (geom.str.length === 1 && lastFontUsed !== geom.fontName && [8242, 48].indexOf(geom.str.charCodeAt(0)) > -1) {
        textDiv.style.top = "".concat(lastTop, "px");
        textDiv.style.fontSize = "".concat(lastHeight, "px");
      }
  
      lastTop = top;
      lastFontUsed = geom.fontName;
      lastHeight = calculatedHeight;
      textDiv.style.fontFamily = style.fontFamily;
      textDiv.textContent = geom.str;
  
      if (task._fontInspectorEnabled) {
        textDiv.dataset.fontName = geom.fontName;
      }
  
      if (angle !== 0) {
        textDivProperties.angle = angle * (180 / Math.PI);
      }
  
      var shouldScaleText = false;
  
      if (geom.str.length > 1) {
        shouldScaleText = true;
      } else if (geom.transform[0] !== geom.transform[3]) {
        var absScaleX = Math.abs(geom.transform[0]),
            absScaleY = Math.abs(geom.transform[3]);
  
        if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) {
          shouldScaleText = true;
        }
      }
  
      if (shouldScaleText) {
        if (style.vertical) {
          textDivProperties.canvasWidth = geom.height * task._viewport.scale;
        } else {
          textDivProperties.canvasWidth = geom.width * task._viewport.scale;
        }
      }
  
      task._textDivProperties.set(textDiv, textDivProperties);
  
      if (task._textContentStream) {
        task._layoutText(textDiv);
      }
  
      if (task._enhanceTextSelection) {
        var angleCos = 1,
            angleSin = 0;
  
        if (angle !== 0) {
          angleCos = Math.cos(angle);
          angleSin = Math.sin(angle);
          if (Math.abs(angleCos) < 0.001) angleCos = 0;
          if (Math.abs(angleSin) < 0.001) angleSin = 0;
        }
  
        var divWidth = (style.vertical ? geom.height : geom.width) * task._viewport.scale;
        divHeight = calculatedHeight;
        var m, b;
  
        if (angle !== 0) {
          m = [angleCos, angleSin, -angleSin, angleCos, left, top];
          b = _util_metapdf.Util.getAxialAlignedBoundingBox([0, 0, divWidth, divHeight], m);
        } else {
          b = [left, top, left + divWidth, top + divHeight];
        }
  
        task._bounds.push({
          left: b[0],
          top: b[1],
          right: b[2],
          bottom: b[3],
          div: textDiv,
          size: [divWidth, divHeight],
          m: m
        });
      }
    }
  
    function render(task) {
      if (task._canceled) {
        return;
      }
  
      var textDivs = task._textDivs;
      var capability = task._capability;
      var textDivsLength = textDivs.length;
  
      if (textDivsLength > MAX_TEXT_DIVS_TO_RENDER) {
        task._renderingDone = true;
        capability.resolve();
        return;
      }
  
      if (!task._textContentStream) {
        for (var i = 0; i < textDivsLength; i++) {
          task._layoutText(textDivs[i]);
        }
      }
  
      task._renderingDone = true;
      capability.resolve();
    }
  
    function findPositiveMin(ts, offset, count) {
      var result = 0;
  
      for (var i = 0; i < count; i++) {
        var t = ts[offset++];
  
        if (t > 0) {
          result = result ? Math.min(t, result) : t;
        }
      }
  
      return result;
    }
  
    function expand(task) {
      var bounds = task._bounds;
      var viewport = task._viewport;
      var expanded = expandBounds(viewport.width, viewport.height, bounds);
  
      var _loop = function _loop(i) {
        var div = bounds[i].div;
  
        var divProperties = task._textDivProperties.get(div);
  
        if (divProperties.angle === 0) {
          divProperties.paddingLeft = bounds[i].left - expanded[i].left;
          divProperties.paddingTop = bounds[i].top - expanded[i].top;
          divProperties.paddingRight = expanded[i].right - bounds[i].right;
          divProperties.paddingBottom = expanded[i].bottom - bounds[i].bottom;
          if (divProperties.paddingTop > 50) divProperties.paddingTop = 0;
          if (divProperties.paddingBottom > 50) divProperties.paddingBottom = 0;
  
          task._textDivProperties.set(div, divProperties);
  
          return "continue";
        }
  
        var e = expanded[i],
            b = bounds[i];
        var m = b.m,
            c = m[0],
            s = m[1];
        var points = [[0, 0], [0, b.size[1]], [b.size[0], 0], b.size];
        var ts = new Float64Array(64);
        points.forEach(function (p, j) {
          var t = _util_metapdf.Util.applyTransform(p, m);
  
          ts[j + 0] = c && (e.left - t[0]) / c;
          ts[j + 4] = s && (e.top - t[1]) / s;
          ts[j + 8] = c && (e.right - t[0]) / c;
          ts[j + 12] = s && (e.bottom - t[1]) / s;
          ts[j + 16] = s && (e.left - t[0]) / -s;
          ts[j + 20] = c && (e.top - t[1]) / c;
          ts[j + 24] = s && (e.right - t[0]) / -s;
          ts[j + 28] = c && (e.bottom - t[1]) / c;
          ts[j + 32] = c && (e.left - t[0]) / -c;
          ts[j + 36] = s && (e.top - t[1]) / -s;
          ts[j + 40] = c && (e.right - t[0]) / -c;
          ts[j + 44] = s && (e.bottom - t[1]) / -s;
          ts[j + 48] = s && (e.left - t[0]) / s;
          ts[j + 52] = c && (e.top - t[1]) / -c;
          ts[j + 56] = s && (e.right - t[0]) / s;
          ts[j + 60] = c && (e.bottom - t[1]) / -c;
        });
        var boxScale = 1 + Math.min(Math.abs(c), Math.abs(s));
        divProperties.paddingLeft = findPositiveMin(ts, 32, 16) / boxScale;
        divProperties.paddingTop = findPositiveMin(ts, 48, 16) / boxScale;
        divProperties.paddingRight = findPositiveMin(ts, 0, 16) / boxScale;
        divProperties.paddingBottom = findPositiveMin(ts, 16, 16) / boxScale;
  
        task._textDivProperties.set(div, divProperties);
      };
  
      for (var i = 0; i < expanded.length; i++) {
        var _ret = _loop(i);
  
        if (_ret === "continue") continue;
      }
    }
  
    function expandBounds(width, height, boxes) {
      var bounds = boxes.map(function (box, i) {
        return {
          x1: box.left,
          y1: box.top,
          x2: box.right,
          y2: box.bottom,
          index: i,
          x1New: undefined,
          x2New: undefined
        };
      });
      expandBoundsLTR(width, bounds);
      var expanded = new Array(boxes.length);
      bounds.forEach(function (b) {
        var i = b.index;
        expanded[i] = {
          left: b.x1New,
          top: 0,
          right: b.x2New,
          bottom: 0
        };
      });
      boxes.map(function (box, i) {
        var e = expanded[i],
            b = bounds[i];
        b.x1 = box.top;
        b.y1 = width - e.right;
        b.x2 = box.bottom;
        b.y2 = width - e.left;
        b.index = i;
        b.x1New = undefined;
        b.x2New = undefined;
      });
      expandBoundsLTR(height, bounds);
      bounds.forEach(function (b) {
        var i = b.index;
        expanded[i].top = b.x1New;
        expanded[i].bottom = b.x2New;
      });
      return expanded;
    }
  
    function expandBoundsLTR(width, bounds) {
      bounds.sort(function (a, b) {
        return a.x1 - b.x1 || a.index - b.index;
      });
      var fakeBoundary = {
        x1: -Infinity,
        y1: -Infinity,
        x2: 0,
        y2: Infinity,
        index: -1,
        x1New: 0,
        x2New: 0
      };
      var horizon = [{
        start: -Infinity,
        end: Infinity,
        boundary: fakeBoundary
      }];
      bounds.forEach(function (boundary) {
        var i = 0;
  
        while (i < horizon.length && horizon[i].end <= boundary.y1) {
          i++;
        }
  
        var j = horizon.length - 1;
  
        while (j >= 0 && horizon[j].start >= boundary.y2) {
          j--;
        }
  
        var horizonPart, affectedBoundary;
        var q,
            k,
            maxXNew = -Infinity;
  
        for (q = i; q <= j; q++) {
          horizonPart = horizon[q];
          affectedBoundary = horizonPart.boundary;
          var xNew = void 0;
  
          if (affectedBoundary.x2 > boundary.x1) {
            xNew = affectedBoundary.index > boundary.index ? affectedBoundary.x1New : boundary.x1;
          } else if (affectedBoundary.x2New === undefined) {
            xNew = (affectedBoundary.x2 + boundary.x1) / 2;
          } else {
            xNew = affectedBoundary.x2New;
          }
  
          if (xNew > maxXNew) {
            maxXNew = xNew;
          }
        }
  
        boundary.x1New = maxXNew;
  
        for (q = i; q <= j; q++) {
          horizonPart = horizon[q];
          affectedBoundary = horizonPart.boundary;
  
          if (affectedBoundary.x2New === undefined) {
            if (affectedBoundary.x2 > boundary.x1) {
              if (affectedBoundary.index > boundary.index) {
                affectedBoundary.x2New = affectedBoundary.x2;
              }
            } else {
              affectedBoundary.x2New = maxXNew;
            }
          } else if (affectedBoundary.x2New > maxXNew) {
            affectedBoundary.x2New = Math.max(maxXNew, affectedBoundary.x2);
          }
        }
  
        var changedHorizon = [];
        var lastBoundary = null;
  
        for (q = i; q <= j; q++) {
          horizonPart = horizon[q];
          affectedBoundary = horizonPart.boundary;
          var useBoundary = affectedBoundary.x2 > boundary.x2 ? affectedBoundary : boundary;
  
          if (lastBoundary === useBoundary) {
            changedHorizon[changedHorizon.length - 1].end = horizonPart.end;
          } else {
            changedHorizon.push({
              start: horizonPart.start,
              end: horizonPart.end,
              boundary: useBoundary
            });
            lastBoundary = useBoundary;
          }
        }
  
        if (horizon[i] && horizon[i].start < boundary.y1) {
          if (changedHorizon[0]) {
            changedHorizon[0].start = boundary.y1;
          }
  
          changedHorizon.unshift({
            start: horizon[i].start,
            end: boundary.y1,
            boundary: horizon[i].boundary
          });
        }
  
        if (boundary.y2 < horizon[j].end) {
          if (changedHorizon[changedHorizon.length - 1]) {
            changedHorizon[changedHorizon.length - 1].end = boundary.y2;
          }
  
          changedHorizon.push({
            start: boundary.y2,
            end: horizon[j].end,
            boundary: horizon[j].boundary
          });
        }
  
        for (q = i; q <= j; q++) {
          horizonPart = horizon[q];
          affectedBoundary = horizonPart.boundary;
  
          if (affectedBoundary.x2New !== undefined) {
            continue;
          }
  
          var used = false;
  
          for (k = i - 1; !used && k >= 0 && horizon[k].start >= affectedBoundary.y1; k--) {
            used = horizon[k].boundary === affectedBoundary;
          }
  
          for (k = j + 1; !used && k < horizon.length && horizon[k].end <= affectedBoundary.y2; k++) {
            used = horizon[k].boundary === affectedBoundary;
          }
  
          for (k = 0; !used && k < changedHorizon.length; k++) {
            used = changedHorizon[k].boundary === affectedBoundary;
          }
  
          if (!used) {
            affectedBoundary.x2New = maxXNew;
          }
        }
  
        Array.prototype.splice.apply(horizon, [i, j - i + 1].concat(changedHorizon));
      });
      horizon.forEach(function (horizonPart) {
        var affectedBoundary = horizonPart.boundary;
  
        if (affectedBoundary.x2New === undefined) {
          affectedBoundary.x2New = Math.max(width, affectedBoundary.x2);
        }
      });
    }
  
    function TextLayerRenderTask(_ref) {
      var _globalThis$FontInspe,
          _this = this;
  
      var textContent = _ref.textContent,
          textContentStream = _ref.textContentStream,
          container = _ref.container,
          viewport = _ref.viewport,
          textDivs = _ref.textDivs,
          textContentItemsStr = _ref.textContentItemsStr,
          enhanceTextSelection = _ref.enhanceTextSelection;
      this._textContent = textContent;
      this._textContentStream = textContentStream;
      this._container = container;
      this._document = container.ownerDocument;
      this._viewport = viewport;
      this._textDivs = textDivs || [];
      this._textContentItemsStr = textContentItemsStr || [];
      this._enhanceTextSelection = !!enhanceTextSelection;
      this._fontInspectorEnabled = !!((_globalThis$FontInspe = globalThis.FontInspector) === null || _globalThis$FontInspe === void 0 ? void 0 : _globalThis$FontInspe.enabled);
      this._reader = null;
      this._layoutTextLastFontSize = null;
      this._layoutTextLastFontFamily = null;
      this._layoutTextCtx = null;
      this._textDivProperties = new WeakMap();
      this._renderingDone = false;
      this._canceled = false;
      this._capability = (0, _util_metapdf.createPromiseCapability)();
      this._renderTimer = null;
      this._bounds = [];
  
      this._capability.promise["finally"](function () {
        if (_this._layoutTextCtx) {
          _this._layoutTextCtx.canvas.width = 0;
          _this._layoutTextCtx.canvas.height = 0;
          _this._layoutTextCtx = null;
        }
      })["catch"](function () {});
    }
  
    TextLayerRenderTask.prototype = {
      get promise() {
        return this._capability.promise;
      },
  
      cancel: function TextLayer_cancel() {
        this._canceled = true;
  
        if (this._reader) {
          this._reader.cancel(new _util_metapdf.AbortException("TextLayer task cancelled."));
  
          this._reader = null;
        }
  
        if (this._renderTimer !== null) {
          clearTimeout(this._renderTimer);
          this._renderTimer = null;
        }
  
        this._capability.reject(new Error("TextLayer task cancelled."));
      },
      _processItems: function _processItems(items, styleCache) {
        for (var i = 0, len = items.length; i < len; i++) {
          this._textContentItemsStr.push(items[i].str);
  
          appendText(this, items[i], styleCache);
        }
      },
      _layoutText: function _layoutText(textDiv) {
        var textDivProperties = this._textDivProperties.get(textDiv);
  
        if (textDivProperties.isWhitespace) {
          return;
        }
  
        var transform = "";
  
        if (textDivProperties.canvasWidth !== 0) {
          var _textDiv$style = textDiv.style,
              fontSize = _textDiv$style.fontSize,
              fontFamily = _textDiv$style.fontFamily;
  
          if (fontSize !== this._layoutTextLastFontSize || fontFamily !== this._layoutTextLastFontFamily) {
            this._layoutTextCtx.font = "".concat(fontSize, " ").concat(fontFamily);
            this._layoutTextLastFontSize = fontSize;
            this._layoutTextLastFontFamily = fontFamily;
          }
  
          var _this$_layoutTextCtx$ = this._layoutTextCtx.measureText(textDiv.textContent),
              width = _this$_layoutTextCtx$.width;
  
          if (width > 0) {
            textDivProperties.scale = textDivProperties.canvasWidth / width;
            transform = "scaleX(".concat(textDivProperties.scale, ")");
          }
        }
  
        if (textDivProperties.angle !== 0) {
          transform = "rotate(".concat(textDivProperties.angle, "deg) ").concat(transform);
        }
  
        if (transform.length > 0) {
          if (this._enhanceTextSelection) {
            textDivProperties.originalTransform = transform;
          }
  
          textDiv.style.transform = transform;
        }
  
        this._textDivProperties.set(textDiv, textDivProperties);
  
        this._container.appendChild(textDiv);
      },
      _render: function TextLayer_render(timeout) {
        var _this2 = this;
  
        var capability = (0, _util_metapdf.createPromiseCapability)();
        var styleCache = Object.create(null);
  
        var canvas = this._document.createElement("canvas");
  
        canvas.mozOpaque = true;
        this._layoutTextCtx = canvas.getContext("2d", {
          alpha: false
        });
  
        if (this._textContent) {
          var textItems = this._textContent.items;
          var textStyles = this._textContent.styles;
  
          this._processItems(textItems, textStyles);
  
          capability.resolve();
        } else if (this._textContentStream) {
          var pump = function pump() {
            _this2._reader.read().then(function (_ref2) {
              var value = _ref2.value,
                  done = _ref2.done;
  
              if (done) {
                capability.resolve();
                return;
              }
  
              Object.assign(styleCache, value.styles);
  
              _this2._processItems(value.items, styleCache);
  
              pump();
            }, capability.reject);
          };
  
          this._reader = this._textContentStream.getReader();
          pump();
        } else {
          throw new Error('Neither "textContent" nor "textContentStream"' + " parameters specified.");
        }
  
        capability.promise.then(function () {
          styleCache = null;
  
          if (!timeout) {
            render(_this2);
          } else {
            _this2._renderTimer = setTimeout(function () {
              render(_this2);
              _this2._renderTimer = null;
            }, timeout);
          }
        }, this._capability.reject);
      },
      expandTextDivs: function TextLayer_expandTextDivs(expandDivs) {
        if (!this._enhanceTextSelection || !this._renderingDone) {
          return;
        }
  
        if (this._bounds !== null) {
          expand(this);
          this._bounds = null;
        }
  
        var transformBuf = [],
            paddingBuf = [];
  
        for (var i = 0, ii = this._textDivs.length; i < ii; i++) {
          var div = this._textDivs[i];
  
          var divProps = this._textDivProperties.get(div);
  
          if (divProps.isWhitespace) {
            continue;
          }
  
          if (expandDivs) {
            transformBuf.length = 0;
            paddingBuf.length = 0;
  
            if (divProps.originalTransform) {
              transformBuf.push(divProps.originalTransform);
            }
  
            if (divProps.paddingTop > 0) {
              paddingBuf.push("".concat(divProps.paddingTop, "px"));
              transformBuf.push("translateY(".concat(-divProps.paddingTop, "px)"));
            } else {
              paddingBuf.push(0);
            }
  
            if (divProps.paddingRight > 0) {
              paddingBuf.push("".concat(divProps.paddingRight / divProps.scale, "px"));
            } else {
              paddingBuf.push(0);
            }
  
            if (divProps.paddingBottom > 0) {
              paddingBuf.push("".concat(divProps.paddingBottom, "px"));
            } else {
              paddingBuf.push(0);
            }
  
            if (divProps.paddingLeft > 0) {
              paddingBuf.push("".concat(divProps.paddingLeft / divProps.scale, "px"));
              transformBuf.push("translateX(".concat(-divProps.paddingLeft / divProps.scale, "px)"));
            } else {
              paddingBuf.push(0);
            }
  
            div.style.padding = paddingBuf.join(" ");
  
            if (transformBuf.length) {
              div.style.transform = transformBuf.join(" ");
            }
          } else {
            div.style.padding = null;
            div.style.transform = divProps.originalTransform;
          }
        }
      }
    };
  
    function renderTextLayer(renderParameters) {
      var task = new TextLayerRenderTask({
        textContent: renderParameters.textContent,
        textContentStream: renderParameters.textContentStream,
        container: renderParameters.container,
        viewport: renderParameters.viewport,
        textDivs: renderParameters.textDivs,
        textContentItemsStr: renderParameters.textContentItemsStr,
        enhanceTextSelection: renderParameters.enhanceTextSelection
      });
  
      task._render(renderParameters.timeout);
  
      return task;
    }
  
    return renderTextLayer;
  }();
  
  exports.renderTextLayer = renderTextLayer;