text: /*!
   * @pixi/text-bitmap - v6.2.1
   * Compiled Tue, 21 Dec 2021 19:56:15 UTC
   *
   * @pixi/text-bitmap is licensed under the MIT License.
   * http://www.opensource.org/licenses/mit-license
   */
  'use strict';
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  var math = require('@pixi/math');
  var settings = require('@pixi/settings');
  var mesh = require('@pixi/mesh');
  var utils = require('@pixi/utils');
  var core = require('@pixi/core');
  var text = require('@pixi/text');
  var constants = require('@pixi/constants');
  var display = require('@pixi/display');
  var loaders = require('@pixi/loaders');
  
  /*! *****************************************************************************
  Copyright (c) Microsoft Corporation. All rights reserved.
  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
  
  THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  MERCHANTABLITY OR NON-INFRINGEMENT.
  
  See the Apache Version 2.0 License for specific language governing permissions
  and limitations under the License.
  ***************************************************************************** */
  /* global Reflect, Promise */
  
  var extendStatics = function(d, b) {
      extendStatics = Object.setPrototypeOf ||
          ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
          function (d, b) { for (var p in b) { if (b.hasOwnProperty(p)) { d[p] = b[p]; } } };
      return extendStatics(d, b);
  };
  
  function __extends(d, b) {
      extendStatics(d, b);
      function __() { this.constructor = d; }
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  }
  
  /* eslint-disable max-len */
  /**
   * Normalized parsed data from .fnt files.
   *
   * @memberof PIXI
   */
  var BitmapFontData = /** @class */ (function () {
      function BitmapFontData() {
          this.info = [];
          this.common = [];
          this.page = [];
          this.char = [];
          this.kerning = [];
          this.distanceField = [];
      }
      return BitmapFontData;
  }());
  
  /**
   * BitmapFont format that's Text-based.
   *
   * @private
   */
  var TextFormat = /** @class */ (function () {
      function TextFormat() {
      }
      /**
       * Check if resource refers to txt font data.
       *
       * @param data
       * @return - True if resource could be treated as font data, false otherwise.
       */
      TextFormat.test = function (data) {
          return typeof data === 'string' && data.indexOf('info face=') === 0;
      };
      /**
       * Convert text font data to a javascript object.
       *
       * @param txt - Raw string data to be converted
       * @return - Parsed font data
       */
      TextFormat.parse = function (txt) {
          // Retrieve data item
          var items = txt.match(/^[a-z]+\s+.+$/gm);
          var rawData = {
              info: [],
              common: [],
              page: [],
              char: [],
              chars: [],
              kerning: [],
              kernings: [],
              distanceField: [],
          };
          for (var i in items) {
              // Extract item name
              var name = items[i].match(/^[a-z]+/gm)[0];
              // Extract item attribute list as string ex.: "width=10"
              var attributeList = items[i].match(/[a-zA-Z]+=([^\s"']+|"([^"]*)")/gm);
              // Convert attribute list into an object
              var itemData = {};
              for (var i_1 in attributeList) {
                  // Split key-value pairs
                  var split = attributeList[i_1].split('=');
                  var key = split[0];
                  // Remove eventual quotes from value
                  var strValue = split[1].replace(/"/gm, '');
                  // Try to convert value into float
                  var floatValue = parseFloat(strValue);
                  // Use string value case float value is NaN
                  var value = isNaN(floatValue) ? strValue : floatValue;
                  itemData[key] = value;
              }
              // Push current item to the resulting data
              rawData[name].push(itemData);
          }
          var font = new BitmapFontData();
          rawData.info.forEach(function (info) { return font.info.push({
              face: info.face,
              size: parseInt(info.size, 10),
          }); });
          rawData.common.forEach(function (common) { return font.common.push({
              lineHeight: parseInt(common.lineHeight, 10),
          }); });
          rawData.page.forEach(function (page) { return font.page.push({
              id: parseInt(page.id, 10),
              file: page.file,
          }); });
          rawData.char.forEach(function (char) { return font.char.push({
              id: parseInt(char.id, 10),
              page: parseInt(char.page, 10),
              x: parseInt(char.x, 10),
              y: parseInt(char.y, 10),
              width: parseInt(char.width, 10),
              height: parseInt(char.height, 10),
              xoffset: parseInt(char.xoffset, 10),
              yoffset: parseInt(char.yoffset, 10),
              xadvance: parseInt(char.xadvance, 10),
          }); });
          rawData.kerning.forEach(function (kerning) { return font.kerning.push({
              first: parseInt(kerning.first, 10),
              second: parseInt(kerning.second, 10),
              amount: parseInt(kerning.amount, 10),
          }); });
          rawData.distanceField.forEach(function (df) { return font.distanceField.push({
              distanceRange: parseInt(df.distanceRange, 10),
              fieldType: df.fieldType,
          }); });
          return font;
      };
      return TextFormat;
  }());
  
  /**
   * BitmapFont format that's XML-based.
   *
   * @private
   */
  var XMLFormat = /** @class */ (function () {
      function XMLFormat() {
      }
      /**
       * Check if resource refers to xml font data.
       *
       * @param data
       * @return - True if resource could be treated as font data, false otherwise.
       */
      XMLFormat.test = function (data) {
          return data instanceof XMLDocument
              && data.getElementsByTagName('page').length
              && data.getElementsByTagName('info')[0].getAttribute('face') !== null;
      };
      /**
       * Convert the XML into BitmapFontData that we can use.
       *
       * @param xml
       * @return - Data to use for BitmapFont
       */
      XMLFormat.parse = function (xml) {
          var data = new BitmapFontData();
          var info = xml.getElementsByTagName('info');
          var common = xml.getElementsByTagName('common');
          var page = xml.getElementsByTagName('page');
          var char = xml.getElementsByTagName('char');
          var kerning = xml.getElementsByTagName('kerning');
          var distanceField = xml.getElementsByTagName('distanceField');
          for (var i = 0; i < info.length; i++) {
              data.info.push({
                  face: info[i].getAttribute('face'),
                  size: parseInt(info[i].getAttribute('size'), 10),
              });
          }
          for (var i = 0; i < common.length; i++) {
              data.common.push({
                  lineHeight: parseInt(common[i].getAttribute('lineHeight'), 10),
              });
          }
          for (var i = 0; i < page.length; i++) {
              data.page.push({
                  id: parseInt(page[i].getAttribute('id'), 10) || 0,
                  file: page[i].getAttribute('file'),
              });
          }
          for (var i = 0; i < char.length; i++) {
              var letter = char[i];
              data.char.push({
                  id: parseInt(letter.getAttribute('id'), 10),
                  page: parseInt(letter.getAttribute('page'), 10) || 0,
                  x: parseInt(letter.getAttribute('x'), 10),
                  y: parseInt(letter.getAttribute('y'), 10),
                  width: parseInt(letter.getAttribute('width'), 10),
                  height: parseInt(letter.getAttribute('height'), 10),
                  xoffset: parseInt(letter.getAttribute('xoffset'), 10),
                  yoffset: parseInt(letter.getAttribute('yoffset'), 10),
                  xadvance: parseInt(letter.getAttribute('xadvance'), 10),
              });
          }
          for (var i = 0; i < kerning.length; i++) {
              data.kerning.push({
                  first: parseInt(kerning[i].getAttribute('first'), 10),
                  second: parseInt(kerning[i].getAttribute('second'), 10),
                  amount: parseInt(kerning[i].getAttribute('amount'), 10),
              });
          }
          for (var i = 0; i < distanceField.length; i++) {
              data.distanceField.push({
                  fieldType: distanceField[i].getAttribute('fieldType'),
                  distanceRange: parseInt(distanceField[i].getAttribute('distanceRange'), 10),
              });
          }
          return data;
      };
      return XMLFormat;
  }());
  
  /**
   * BitmapFont format that's XML-based.
   *
   * @private
   */
  var XMLStringFormat = /** @class */ (function () {
      function XMLStringFormat() {
      }
      /**
       * Check if resource refers to text xml font data.
       *
       * @param data
       * @return - True if resource could be treated as font data, false otherwise.
       */
      XMLStringFormat.test = function (data) {
          if (typeof data === 'string' && data.indexOf('<font>') > -1) {
              var xml = new self.DOMParser().parseFromString(data, 'text/xml');
              return XMLFormat.test(xml);
          }
          return false;
      };
      /**
       * Convert the text XML into BitmapFontData that we can use.
       *
       * @param xmlTxt
       * @return - Data to use for BitmapFont
       */
      XMLStringFormat.parse = function (xmlTxt) {
          var xml = new self.DOMParser().parseFromString(xmlTxt, 'text/xml');
          return XMLFormat.parse(xml);
      };
      return XMLStringFormat;
  }());
  
  // Registered formats, maybe make this extensible in the future?
  var formats = [
      TextFormat,
      XMLFormat,
      XMLStringFormat ];
  /**
   * Auto-detect BitmapFont parsing format based on data.
   * @private
   * @param {any} data - Data to detect format
   * @return {any} Format or null
   */
  function autoDetectFormat(data) {
      for (var i = 0; i < formats.length; i++) {
          if (formats[i].test(data)) {
              return formats[i];
          }
      }
      return null;
  }
  
  // TODO: Prevent code duplication b/w generateFillStyle & Text#generateFillStyle
  /**
   * Generates the fill style. Can automatically generate a gradient based on the fill style being an array
   *
   * @private
   * @param {object} style - The style.
   * @param {string[]} lines - The lines of text.
   * @return {string|number|CanvasGradient} The fill style
   */
  function generateFillStyle(canvas, context, style, resolution, lines, metrics) {
      // TODO: Can't have different types for getter and setter. The getter shouldn't have the number type as
      //       the setter converts to string. See this thread for more details:
      //       https://github.com/microsoft/TypeScript/issues/2521
      var fillStyle = style.fill;
      if (!Array.isArray(fillStyle)) {
          return fillStyle;
      }
      else if (fillStyle.length === 1) {
          return fillStyle[0];
      }
      // the gradient will be evenly spaced out according to how large the array is.
      // ['#FF0000', '#00FF00', '#0000FF'] would created stops at 0.25, 0.5 and 0.75
      var gradient;
      // a dropshadow will enlarge the canvas and result in the gradient being
      // generated with the incorrect dimensions
      var dropShadowCorrection = (style.dropShadow) ? style.dropShadowDistance : 0;
      // should also take padding into account, padding can offset the gradient
      var padding = style.padding || 0;
      var width = (canvas.width / resolution) - dropShadowCorrection - (padding * 2);
      var height = (canvas.height / resolution) - dropShadowCorrection - (padding * 2);
      // make a copy of the style settings, so we can manipulate them later
      var fill = fillStyle.slice();
      var fillGradientStops = style.fillGradientStops.slice();
      // wanting to evenly distribute the fills. So an array of 4 colours should give fills of 0.25, 0.5 and 0.75
      if (!fillGradientStops.length) {
          var lengthPlus1 = fill.length + 1;
          for (var i = 1; i < lengthPlus1; ++i) {
              fillGradientStops.push(i / lengthPlus1);
          }
      }
      // stop the bleeding of the last gradient on the line above to the top gradient of the this line
      // by hard defining the first gradient colour at point 0, and last gradient colour at point 1
      fill.unshift(fillStyle[0]);
      fillGradientStops.unshift(0);
      fill.push(fillStyle[fillStyle.length - 1]);
      fillGradientStops.push(1);
      if (style.fillGradientType === text.TEXT_GRADIENT.LINEAR_VERTICAL) {
          // start the gradient at the top center of the canvas, and end at the bottom middle of the canvas
          gradient = context.createLinearGradient(width / 2, padding, width / 2, height + padding);
          // we need to repeat the gradient so that each individual line of text has the same vertical gradient effect
          // ['#FF0000', '#00FF00', '#0000FF'] over 2 lines would create stops at 0.125, 0.25, 0.375, 0.625, 0.75, 0.875
          // There's potential for floating point precision issues at the seams between gradient repeats.
          // The loop below generates the stops in order, so track the last generated one to prevent
          // floating point precision from making us go the teeniest bit backwards, resulting in
          // the first and last colors getting swapped.
          var lastIterationStop = 0;
          // Actual height of the text itself, not counting spacing for lineHeight/leading/dropShadow etc
          var textHeight = metrics.fontProperties.fontSize + style.strokeThickness;
          // textHeight, but as a 0-1 size in global gradient stop space
          var gradStopLineHeight = textHeight / height;
          for (var i = 0; i < lines.length; i++) {
              var thisLineTop = metrics.lineHeight * i;
              for (var j = 0; j < fill.length; j++) {
                  // 0-1 stop point for the current line, multiplied to global space afterwards
                  var lineStop = 0;
                  if (typeof fillGradientStops[j] === 'number') {
                      lineStop = fillGradientStops[j];
                  }
                  else {
                      lineStop = j / fill.length;
                  }
                  var globalStop = (thisLineTop / height) + (lineStop * gradStopLineHeight);
                  // Prevent color stop generation going backwards from floating point imprecision
                  var clampedStop = Math.max(lastIterationStop, globalStop);
                  clampedStop = Math.min(clampedStop, 1); // Cap at 1 as well for safety's sake to avoid a possible throw.
                  gradient.addColorStop(clampedStop, fill[j]);
                  lastIterationStop = clampedStop;
              }
          }
      }
      else {
          // start the gradient at the center left of the canvas, and end at the center right of the canvas
          gradient = context.createLinearGradient(padding, height / 2, width + padding, height / 2);
          // can just evenly space out the gradients in this case, as multiple lines makes no difference
          // to an even left to right gradient
          var totalIterations = fill.length + 1;
          var currentIteration = 1;
          for (var i = 0; i < fill.length; i++) {
              var stop = void 0;
              if (typeof fillGradientStops[i] === 'number') {
                  stop = fillGradientStops[i];
              }
              else {
                  stop = currentIteration / totalIterations;
              }
              gradient.addColorStop(stop, fill[i]);
              currentIteration++;
          }
      }
      return gradient;
  }
  
  // TODO: Prevent code duplication b/w drawGlyph & Text#updateText
  /**
   * Draws the glyph `metrics.text` on the given canvas.
   *
   * Ignored because not directly exposed.
   *
   * @ignore
   * @param {HTMLCanvasElement} canvas
   * @param {CanvasRenderingContext2D} context
   * @param {TextMetrics} metrics
   * @param {number} x
   * @param {number} y
   * @param {number} resolution
   * @param {TextStyle} style
   */
  function drawGlyph(canvas, context, metrics, x, y, resolution, style) {
      var char = metrics.text;
      var fontProperties = metrics.fontProperties;
      context.translate(x, y);
      context.scale(resolution, resolution);
      var tx = style.strokeThickness / 2;
      var ty = -(style.strokeThickness / 2);
      context.font = style.toFontString();
      context.lineWidth = style.strokeThickness;
      context.textBaseline = style.textBaseline;
      context.lineJoin = style.lineJoin;
      context.miterLimit = style.miterLimit;
      // set canvas text styles
      context.fillStyle = generateFillStyle(canvas, context, style, resolution, [char], metrics);
      context.strokeStyle = style.stroke;
      var dropShadowColor = style.dropShadowColor;
      var rgb = utils.hex2rgb(typeof dropShadowColor === 'number' ? dropShadowColor : utils.string2hex(dropShadowColor));
      if (style.dropShadow) {
          context.shadowColor = "rgba(" + rgb[0] * 255 + "," + rgb[1] * 255 + "," + rgb[2] * 255 + "," + style.dropShadowAlpha + ")";
          context.shadowBlur = style.dropShadowBlur;
          context.shadowOffsetX = Math.cos(style.dropShadowAngle) * style.dropShadowDistance;
          context.shadowOffsetY = Math.sin(style.dropShadowAngle) * style.dropShadowDistance;
      }
      else {
          context.shadowColor = 'black';
          context.shadowBlur = 0;
          context.shadowOffsetX = 0;
          context.shadowOffsetY = 0;
      }
      if (style.stroke && style.strokeThickness) {
          context.strokeText(char, tx, ty + metrics.lineHeight - fontProperties.descent);
      }
      if (style.fill) {
          context.fillText(char, tx, ty + metrics.lineHeight - fontProperties.descent);
      }
      context.setTransform(1, 0, 0, 1, 0, 0); // defaults needed for older browsers (e.g. Opera 29)
      context.fillStyle = 'rgba(0, 0, 0, 0)';
  }
  
  /**
   * Ponyfill for IE because it doesn't support `Array.from`
   * @private
   */
  function splitTextToCharacters(text) {
      return Array.from ? Array.from(text) : text.split('');
  }
  
  /**
   * Processes the passed character set data and returns a flattened array of all the characters.
   *
   * Ignored because not directly exposed.
   *
   * @ignore
   * @param {string | string[] | string[][] } chars
   * @returns {string[]}
   */
  function resolveCharacters(chars) {
      // Split the chars string into individual characters
      if (typeof chars === 'string') {
          chars = [chars];
      }
      // Handle an array of characters+ranges
      var result = [];
      for (var i = 0, j = chars.length; i < j; i++) {
          var item = chars[i];
          // Handle range delimited by start/end chars
          if (Array.isArray(item)) {
              if (item.length !== 2) {
                  throw new Error("[BitmapFont]: Invalid character range length, expecting 2 got " + item.length + ".");
              }
              var startCode = item[0].charCodeAt(0);
              var endCode = item[1].charCodeAt(0);
              if (endCode < startCode) {
                  throw new Error('[BitmapFont]: Invalid character range.');
              }
              for (var i_1 = startCode, j_1 = endCode; i_1 <= j_1; i_1++) {
                  result.push(String.fromCharCode(i_1));
              }
          }
          // Handle a character set string
          else {
              result.push.apply(result, splitTextToCharacters(item));
          }
      }
      if (result.length === 0) {
          throw new Error('[BitmapFont]: Empty set when resolving characters.');
      }
      return result;
  }
  
  /**
   * Ponyfill for IE because it doesn't support `codePointAt`
   * @private
   */
  function extractCharCode(str) {
      return str.codePointAt ? str.codePointAt(0) : str.charCodeAt(0);
  }
  
  /**
   * BitmapFont represents a typeface available for use with the BitmapText class. Use the `install`
   * method for adding a font to be used.
   *
   * @memberof PIXI
   */
  var BitmapFont = /** @class */ (function () {
      /**
       * @param data
       * @param textures
       * @param ownsTextures - Setting to `true` will destroy page textures
       *        when the font is uninstalled.
       */
      function BitmapFont(data, textures, ownsTextures) {
          var _a, _b;
          var info = data.info[0];
          var common = data.common[0];
          var page = data.page[0];
          var distanceField = data.distanceField[0];
          var res = utils.getResolutionOfUrl(page.file);
          var pageTextures = {};
          this._ownsTextures = ownsTextures;
          this.font = info.face;
          this.size = info.size;
          this.lineHeight = common.lineHeight / res;
          this.chars = {};
          this.pageTextures = pageTextures;
          // Convert the input Texture, Textures or object
          // into a page Texture lookup by "id"
          for (var i = 0; i < data.page.length; i++) {
              var _c = data.page[i], id = _c.id, file = _c.file;
              pageTextures[id] = textures instanceof Array
                  ? textures[i] : textures[file];
              // only MSDF and SDF fonts need no-premultiplied-alpha
              if ((distanceField === null || distanceField === void 0 ? void 0 : distanceField.fieldType) && distanceField.fieldType !== 'none') {
                  pageTextures[id].baseTexture.alphaMode = constants.ALPHA_MODES.NO_PREMULTIPLIED_ALPHA;
              }
          }
          // parse letters
          for (var i = 0; i < data.char.length; i++) {
              var _d = data.char[i], id = _d.id, page_1 = _d.page;
              var _e = data.char[i], x = _e.x, y = _e.y, width = _e.width, height = _e.height, xoffset = _e.xoffset, yoffset = _e.yoffset, xadvance = _e.xadvance;
              x /= res;
              y /= res;
              width /= res;
              height /= res;
              xoffset /= res;
              yoffset /= res;
              xadvance /= res;
              var rect = new math.Rectangle(x + (pageTextures[page_1].frame.x / res), y + (pageTextures[page_1].frame.y / res), width, height);
              this.chars[id] = {
                  xOffset: xoffset,
                  yOffset: yoffset,
                  xAdvance: xadvance,
                  kerning: {},
                  texture: new core.Texture(pageTextures[page_1].baseTexture, rect),
                  page: page_1,
              };
          }
          // parse kernings
          for (var i = 0; i < data.kerning.length; i++) {
              var _f = data.kerning[i], first = _f.first, second = _f.second, amount = _f.amount;
              first /= res;
              second /= res;
              amount /= res;
              if (this.chars[second]) {
                  this.chars[second].kerning[first] = amount;
              }
          }
          // Store distance field information
          this.distanceFieldRange = distanceField === null || distanceField === void 0 ? void 0 : distanceField.distanceRange;
          this.distanceFieldType = (_b = (_a = distanceField === null || distanceField === void 0 ? void 0 : distanceField.fieldType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : 'none';
      }
      /** Remove references to created glyph textures. */
      BitmapFont.prototype.destroy = function () {
          for (var id in this.chars) {
              this.chars[id].texture.destroy();
              this.chars[id].texture = null;
          }
          for (var id in this.pageTextures) {
              if (this._ownsTextures) {
                  this.pageTextures[id].destroy(true);
              }
              this.pageTextures[id] = null;
          }
          // Set readonly null.
          this.chars = null;
          this.pageTextures = null;
      };
      /**
       * Register a new bitmap font.
       *
       * @param data - The
       *        characters map that could be provided as xml or raw string.
       * @param textures - List of textures for each page.
       * @param ownsTextures - Set to `true` to destroy page textures
       *        when the font is uninstalled. By default fonts created with
       *        `BitmapFont.from` or from the `BitmapFontLoader` are `true`.
       * @return {PIXI.BitmapFont} Result font object with font, size, lineHeight
       *         and char fields.
       */
      BitmapFont.install = function (data, textures, ownsTextures) {
          var fontData;
          if (data instanceof BitmapFontData) {
              fontData = data;
          }
          else {
              var format = autoDetectFormat(data);
              if (!format) {
                  throw new Error('Unrecognized data format for font.');
              }
              fontData = format.parse(data);
          }
          // Single texture, convert to list
          if (textures instanceof core.Texture) {
              textures = [textures];
          }
          var font = new BitmapFont(fontData, textures, ownsTextures);
          BitmapFont.available[font.font] = font;
          return font;
      };
      /**
       * Remove bitmap font by name.
       *
       * @param name - Name of the font to uninstall.
       */
      BitmapFont.uninstall = function (name) {
          var font = BitmapFont.available[name];
          if (!font) {
              throw new Error("No font found named '" + name + "'");
          }
          font.destroy();
          delete BitmapFont.available[name];
      };
      /**
       * Generates a bitmap-font for the given style and character set. This does not support
       * kernings yet. With `style` properties, only the following non-layout properties are used:
       *
       * - {@link PIXI.TextStyle#dropShadow|dropShadow}
       * - {@link PIXI.TextStyle#dropShadowDistance|dropShadowDistance}
       * - {@link PIXI.TextStyle#dropShadowColor|dropShadowColor}
       * - {@link PIXI.TextStyle#dropShadowBlur|dropShadowBlur}
       * - {@link PIXI.TextStyle#dropShadowAngle|dropShadowAngle}
       * - {@link PIXI.TextStyle#fill|fill}
       * - {@link PIXI.TextStyle#fillGradientStops|fillGradientStops}
       * - {@link PIXI.TextStyle#fillGradientType|fillGradientType}
       * - {@link PIXI.TextStyle#fontFamily|fontFamily}
       * - {@link PIXI.TextStyle#fontSize|fontSize}
       * - {@link PIXI.TextStyle#fontVariant|fontVariant}
       * - {@link PIXI.TextStyle#fontWeight|fontWeight}
       * - {@link PIXI.TextStyle#lineJoin|lineJoin}
       * - {@link PIXI.TextStyle#miterLimit|miterLimit}
       * - {@link PIXI.TextStyle#stroke|stroke}
       * - {@link PIXI.TextStyle#strokeThickness|strokeThickness}
       * - {@link PIXI.TextStyle#textBaseline|textBaseline}
       *
       * @param name - The name of the custom font to use with BitmapText.
       * @param style - Style options to render with BitmapFont.
       * @param options - Setup options for font or name of the font.
       * @param {string|string[]|string[][]} [options.chars=PIXI.BitmapFont.ALPHANUMERIC] - characters included
       *      in the font set. You can also use ranges. For example, `[['a', 'z'], ['A', 'Z'], "!@#$%^&*()~{}[] "]`.
       *      Don't forget to include spaces ' ' in your character set!
       * @param {number} [options.resolution=1] - Render resolution for glyphs.
       * @param {number} [options.textureWidth=512] - Optional width of atlas, smaller values to reduce memory.
       * @param {number} [options.textureHeight=512] - Optional height of atlas, smaller values to reduce memory.
       * @param {number} [options.padding=4] - Padding between glyphs on texture atlas.
       * @return Font generated by style options.
       * @example
       * PIXI.BitmapFont.from("TitleFont", {
       *     fontFamily: "Arial",
       *     fontSize: 12,
       *     strokeThickness: 2,
       *     fill: "purple"
       * });
       *
       * const title = new PIXI.BitmapText("This is the title", { fontName: "TitleFont" });
       */
      BitmapFont.from = function (name, textStyle, options) {
          if (!name) {
              throw new Error('[BitmapFont] Property `name` is required.');
          }
          var _a = Object.assign({}, BitmapFont.defaultOptions, options), chars = _a.chars, padding = _a.padding, resolution = _a.resolution, textureWidth = _a.textureWidth, textureHeight = _a.textureHeight;
          var charsList = resolveCharacters(chars);
          var style = textStyle instanceof text.TextStyle ? textStyle : new text.TextStyle(textStyle);
          var lineWidth = textureWidth;
          var fontData = new BitmapFontData();
          fontData.info[0] = {
              face: style.fontFamily,
              size: style.fontSize,
          };
          fontData.common[0] = {
              lineHeight: style.fontSize,
          };
          var positionX = 0;
          var positionY = 0;
          var canvas;
          var context;
          var baseTexture;
          var maxCharHeight = 0;
          var textures = [];
          for (var i = 0; i < charsList.length; i++) {
              if (!canvas) {
                  canvas = document.createElement('canvas');
                  canvas.width = textureWidth;
                  canvas.height = textureHeight;
                  context = canvas.getContext('2d');
                  baseTexture = new core.BaseTexture(canvas, { resolution: resolution });
                  textures.push(new core.Texture(baseTexture));
                  fontData.page.push({
                      id: textures.length - 1,
                      file: '',
                  });
              }
              // Measure glyph dimensions
              var metrics = text.TextMetrics.measureText(charsList[i], style, false, canvas);
              var width = metrics.width;
              var height = Math.ceil(metrics.height);
              // This is ugly - but italics are given more space so they don't overlap
              var textureGlyphWidth = Math.ceil((style.fontStyle === 'italic' ? 2 : 1) * width);
              // Can't fit char anymore: next canvas please!
              if (positionY >= textureHeight - (height * resolution)) {
                  if (positionY === 0) {
                      // We don't want user debugging an infinite loop (or do we? :)
                      throw new Error("[BitmapFont] textureHeight " + textureHeight + "px is "
                          + ("too small for " + style.fontSize + "px fonts"));
                  }
                  --i;
                  // Create new atlas once current has filled up
                  canvas = null;
                  context = null;
                  baseTexture = null;
                  positionY = 0;
                  positionX = 0;
                  maxCharHeight = 0;
                  continue;
              }
              maxCharHeight = Math.max(height + metrics.fontProperties.descent, maxCharHeight);
              // Wrap line once full row has been rendered
              if ((textureGlyphWidth * resolution) + positionX >= lineWidth) {
                  --i;
                  positionY += maxCharHeight * resolution;
                  positionY = Math.ceil(positionY);
                  positionX = 0;
                  maxCharHeight = 0;
                  continue;
              }
              drawGlyph(canvas, context, metrics, positionX, positionY, resolution, style);
              // Unique (numeric) ID mapping to this glyph
              var id = extractCharCode(metrics.text);
              // Create a texture holding just the glyph
              fontData.char.push({
                  id: id,
                  page: textures.length - 1,
                  x: positionX / resolution,
                  y: positionY / resolution,
                  width: textureGlyphWidth,
                  height: height,
                  xoffset: 0,
                  yoffset: 0,
                  xadvance: Math.ceil(width
                      - (style.dropShadow ? style.dropShadowDistance : 0)
                      - (style.stroke ? style.strokeThickness : 0)),
              });
              positionX += (textureGlyphWidth + (2 * padding)) * resolution;
              positionX = Math.ceil(positionX);
          }
          // Brute-force kerning info, this can be expensive b/c it's an O(n²),
          // but we're using measureText which is native and fast.
          for (var i = 0, len = charsList.length; i < len; i++) {
              var first = charsList[i];
              for (var j = 0; j < len; j++) {
                  var second = charsList[j];
                  var c1 = context.measureText(first).width;
                  var c2 = context.measureText(second).width;
                  var total = context.measureText(first + second).width;
                  var amount = total - (c1 + c2);
                  if (amount) {
                      fontData.kerning.push({
                          first: extractCharCode(first),
                          second: extractCharCode(second),
                          amount: amount,
                      });
                  }
              }
          }
          var font = new BitmapFont(fontData, textures, true);
          // Make it easier to replace a font
          if (BitmapFont.available[name] !== undefined) {
              BitmapFont.uninstall(name);
          }
          BitmapFont.available[name] = font;
          return font;
      };
      /**
       * This character set includes all the letters in the alphabet (both lower- and upper- case).
       *
       * @type {string[][]}
       * @example
       * BitmapFont.from("ExampleFont", style, { chars: BitmapFont.ALPHA })
       */
      BitmapFont.ALPHA = [['a', 'z'], ['A', 'Z'], ' '];
      /**
       * This character set includes all decimal digits (from 0 to 9).
       *
       * @type {string[][]}
       * @example
       * BitmapFont.from("ExampleFont", style, { chars: BitmapFont.NUMERIC })
       */
      BitmapFont.NUMERIC = [['0', '9']];
      /**
       * This character set is the union of `BitmapFont.ALPHA` and `BitmapFont.NUMERIC`.
       *
       * @type {string[][]}
       */
      BitmapFont.ALPHANUMERIC = [['a', 'z'], ['A', 'Z'], ['0', '9'], ' '];
      /**
       * This character set consists of all the ASCII table.
       *
       * @member {string[][]}
       * @see http://www.asciitable.com/
       */
      BitmapFont.ASCII = [[' ', '~']];
      /**
       * Collection of default options when using `BitmapFont.from`.
       *
       * @property {number} resolution=1
       * @property {number} textureWidth=512
       * @property {number} textureHeight=512
       * @property {number} padding=4
       * @property {string|string[]|string[][]} chars = PIXI.BitmapFont.ALPHANUMERIC
       */
      BitmapFont.defaultOptions = {
          resolution: 1,
          textureWidth: 512,
          textureHeight: 512,
          padding: 4,
          chars: BitmapFont.ALPHANUMERIC,
      };
      /** Collection of available/installed fonts. */
      BitmapFont.available = {};
      return BitmapFont;
  }());
  
  var msdfFrag = "// Pixi texture info\r\nvarying vec2 vTextureCoord;\r\nuniform sampler2D uSampler;\r\n\r\n// Tint\r\nuniform vec4 uColor;\r\n\r\n// on 2D applications fwidth is screenScale / glyphAtlasScale * distanceFieldRange\r\nuniform float uFWidth;\r\n\r\nvoid main(void) {\r\n\r\n  // To stack MSDF and SDF we need a non-pre-multiplied-alpha texture.\r\n  vec4 texColor = texture2D(uSampler, vTextureCoord);\r\n\r\n  // MSDF\r\n  float median = texColor.r + texColor.g + texColor.b -\r\n                  min(texColor.r, min(texColor.g, texColor.b)) -\r\n                  max(texColor.r, max(texColor.g, texColor.b));\r\n  // SDF\r\n  median = min(median, texColor.a);\r\n\r\n  float screenPxDistance = uFWidth * (median - 0.5);\r\n  float alpha = clamp(screenPxDistance + 0.5, 0.0, 1.0);\r\n\r\n  // NPM Textures, NPM outputs\r\n  gl_FragColor = vec4(uColor.rgb, uColor.a * alpha);\r\n\r\n}\r\n";
  
  var msdfVert = "// Mesh material default fragment\r\nattribute vec2 aVertexPosition;\r\nattribute vec2 aTextureCoord;\r\n\r\nuniform mat3 projectionMatrix;\r\nuniform mat3 translationMatrix;\r\nuniform mat3 uTextureMatrix;\r\n\r\nvarying vec2 vTextureCoord;\r\n\r\nvoid main(void)\r\n{\r\n    gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);\r\n\r\n    vTextureCoord = (uTextureMatrix * vec3(aTextureCoord, 1.0)).xy;\r\n}\r\n";
  
  // If we ever need more than two pools, please make a Dict or something better.
  var pageMeshDataDefaultPageMeshData = [];
  var pageMeshDataMSDFPageMeshData = [];
  var charRenderDataPool = [];
  /**
   * A BitmapText object will create a line or multiple lines of text using bitmap font.
   *
   * The primary advantage of this class over Text is that all of your textures are pre-generated and loading,
   * meaning that rendering is fast, and changing text has no performance implications.
   *
   * Supporting character sets other than latin, such as CJK languages, may be impractical due to the number of characters.
   *
   * To split a line you can use '\n', '\r' or '\r\n' in your string.
   *
   * PixiJS can auto-generate fonts on-the-fly using BitmapFont or use fnt files provided by:
   * http://www.angelcode.com/products/bmfont/ for Windows or
   * http://www.bmglyph.com/ for Mac.
   *
   * You can also use SDF, MSDF and MTSDF BitmapFonts for vector-like scaling appearance provided by:
   * https://github.com/soimy/msdf-bmfont-xml for SDF and MSDF fnt files or
   * https://github.com/Chlumsky/msdf-atlas-gen for SDF, MSDF and MTSDF json files
   *
   * A BitmapText can only be created when the font is loaded.
   *
   * ```js
   * // in this case the font is in a file called 'desyrel.fnt'
   * let bitmapText = new PIXI.BitmapText("text using a fancy font!", {
   *   fontName: "Desyrel",
   *   fontSize: 35,
   *   align: "right"
   * });
   * ```
   *
   * @memberof PIXI
   */
  var BitmapText = /** @class */ (function (_super) {
      __extends(BitmapText, _super);
      /**
       * @param text - A string that you would like the text to display.
       * @param style - The style parameters.
       * @param {string} style.fontName - The installed BitmapFont name.
       * @param {number} [style.fontSize] - The size of the font in pixels, e.g. 24. If undefined,
       *.     this will default to the BitmapFont size.
       * @param {string} [style.align='left'] - Alignment for multiline text ('left', 'center', 'right' or 'justify'),
       *      does not affect single line text.
       * @param {number} [style.tint=0xFFFFFF] - The tint color.
       * @param {number} [style.letterSpacing=0] - The amount of spacing between letters.
       * @param {number} [style.maxWidth=0] - The max width of the text before line wrapping.
       */
      function BitmapText(text, style) {
          if (style === void 0) { style = {}; }
          var _this = _super.call(this) || this;
          /**
           * Private tracker for the current tint.
           *
           * @private
           */
          _this._tint = 0xFFFFFF;
          // Apply the defaults
          var _a = Object.assign({}, BitmapText.styleDefaults, style), align = _a.align, tint = _a.tint, maxWidth = _a.maxWidth, letterSpacing = _a.letterSpacing, fontName = _a.fontName, fontSize = _a.fontSize;
          if (!BitmapFont.available[fontName]) {
              throw new Error("Missing BitmapFont \"" + fontName + "\"");
          }
          _this._activePagesMeshData = [];
          _this._textWidth = 0;
          _this._textHeight = 0;
          _this._align = align;
          _this._tint = tint;
          _this._fontName = fontName;
          _this._fontSize = fontSize || BitmapFont.available[fontName].size;
          _this._text = text;
          _this._maxWidth = maxWidth;
          _this._maxLineHeight = 0;
          _this._letterSpacing = letterSpacing;
          _this._anchor = new math.ObservablePoint(function () { _this.dirty = true; }, _this, 0, 0);
          _this._roundPixels = settings.settings.ROUND_PIXELS;
          _this.dirty = true;
          _this._textureCache = {};
          return _this;
      }
      /**
       * Renders text and updates it when needed. This should only be called
       * if the BitmapFont is regenerated.
       */
      BitmapText.prototype.updateText = function () {
          var _a;
          var data = BitmapFont.available[this._fontName];
          var scale = this._fontSize / data.size;
          var pos = new math.Point();
          var chars = [];
          var lineWidths = [];
          var lineSpaces = [];
          var text = this._text.replace(/(?:\r\n|\r)/g, '\n') || ' ';
          var charsInput = splitTextToCharacters(text);
          var maxWidth = this._maxWidth * data.size / this._fontSize;
          var pageMeshDataPool = data.distanceFieldType === 'none'
              ? pageMeshDataDefaultPageMeshData : pageMeshDataMSDFPageMeshData;
          var prevCharCode = null;
          var lastLineWidth = 0;
          var maxLineWidth = 0;
          var line = 0;
          var lastBreakPos = -1;
          var lastBreakWidth = 0;
          var spacesRemoved = 0;
          var maxLineHeight = 0;
          var spaceCount = 0;
          for (var i = 0; i < charsInput.length; i++) {
              var char = charsInput[i];
              var charCode = extractCharCode(char);
              if ((/(?:\s)/).test(char)) {
                  lastBreakPos = i;
                  lastBreakWidth = lastLineWidth;
                  spaceCount++;
              }
              if (char === '\r' || char === '\n') {
                  lineWidths.push(lastLineWidth);
                  lineSpaces.push(-1);
                  maxLineWidth = Math.max(maxLineWidth, lastLineWidth);
                  ++line;
                  ++spacesRemoved;
                  pos.x = 0;
                  pos.y += data.lineHeight;
                  prevCharCode = null;
                  spaceCount = 0;
                  continue;
              }
              var charData = data.chars[charCode];
              if (!charData) {
                  continue;
              }
              if (prevCharCode && charData.kerning[prevCharCode]) {
                  pos.x += charData.kerning[prevCharCode];
              }
              var charRenderData = charRenderDataPool.pop() || {
                  texture: core.Texture.EMPTY,
                  line: 0,
                  charCode: 0,
                  prevSpaces: 0,
                  position: new math.Point(),
              };
              charRenderData.texture = charData.texture;
              charRenderData.line = line;
              charRenderData.charCode = charCode;
              charRenderData.position.x = pos.x + charData.xOffset + (this._letterSpacing / 2);
              charRenderData.position.y = pos.y + charData.yOffset;
              charRenderData.prevSpaces = spaceCount;
              chars.push(charRenderData);
              lastLineWidth = charRenderData.position.x + charData.texture.orig.width; // Use charRenderData position!
              pos.x += charData.xAdvance + this._letterSpacing;
              maxLineHeight = Math.max(maxLineHeight, (charData.yOffset + charData.texture.height));
              prevCharCode = charCode;
              if (lastBreakPos !== -1 && maxWidth > 0 && pos.x > maxWidth) {
                  ++spacesRemoved;
                  utils.removeItems(chars, 1 + lastBreakPos - spacesRemoved, 1 + i - lastBreakPos);
                  i = lastBreakPos;
                  lastBreakPos = -1;
                  lineWidths.push(lastBreakWidth);
                  lineSpaces.push(chars.length > 0 ? chars[chars.length - 1].prevSpaces : 0);
                  maxLineWidth = Math.max(maxLineWidth, lastBreakWidth);
                  line++;
                  pos.x = 0;
                  pos.y += data.lineHeight;
                  prevCharCode = null;
                  spaceCount = 0;
              }
          }
          var lastChar = charsInput[charsInput.length - 1];
          if (lastChar !== '\r' && lastChar !== '\n') {
              if ((/(?:\s)/).test(lastChar)) {
                  lastLineWidth = lastBreakWidth;
              }
              lineWidths.push(lastLineWidth);
              maxLineWidth = Math.max(maxLineWidth, lastLineWidth);
              lineSpaces.push(-1);
          }
          var lineAlignOffsets = [];
          for (var i = 0; i <= line; i++) {
              var alignOffset = 0;
              if (this._align === 'right') {
                  alignOffset = maxLineWidth - lineWidths[i];
              }
              else if (this._align === 'center') {
                  alignOffset = (maxLineWidth - lineWidths[i]) / 2;
              }
              else if (this._align === 'justify') {
                  alignOffset = lineSpaces[i] < 0 ? 0 : (maxLineWidth - lineWidths[i]) / lineSpaces[i];
              }
              lineAlignOffsets.push(alignOffset);
          }
          var lenChars = chars.length;
          var pagesMeshData = {};
          var newPagesMeshData = [];
          var activePagesMeshData = this._activePagesMeshData;
          for (var i = 0; i < activePagesMeshData.length; i++) {
              pageMeshDataPool.push(activePagesMeshData[i]);
          }
          for (var i = 0; i < lenChars; i++) {
              var texture = chars[i].texture;
              var baseTextureUid = texture.baseTexture.uid;
              if (!pagesMeshData[baseTextureUid]) {
                  var pageMeshData = pageMeshDataPool.pop();
                  if (!pageMeshData) {
                      var geometry = new mesh.MeshGeometry();
                      var material = void 0;
                      var meshBlendMode = void 0;
                      if (data.distanceFieldType === 'none') {
                          material = new mesh.MeshMaterial(core.Texture.EMPTY);
                          meshBlendMode = constants.BLEND_MODES.NORMAL;
                      }
                      else {
                          material = new mesh.MeshMaterial(core.Texture.EMPTY, { program: core.Program.from(msdfVert, msdfFrag), uniforms: { uFWidth: 0 } });
                          meshBlendMode = constants.BLEND_MODES.NORMAL_NPM;
                      }
                      var mesh$1 = new mesh.Mesh(geometry, material);
                      mesh$1.blendMode = meshBlendMode;
                      pageMeshData = {
                          index: 0,
                          indexCount: 0,
                          vertexCount: 0,
                          uvsCount: 0,
                          total: 0,
                          mesh: mesh$1,
                          vertices: null,
                          uvs: null,
                          indices: null,
                      };
                  }
                  // reset data..
                  pageMeshData.index = 0;
                  pageMeshData.indexCount = 0;
                  pageMeshData.vertexCount = 0;
                  pageMeshData.uvsCount = 0;
                  pageMeshData.total = 0;
                  // TODO need to get page texture here somehow..
                  var _textureCache = this._textureCache;
                  _textureCache[baseTextureUid] = _textureCache[baseTextureUid] || new core.Texture(texture.baseTexture);
                  pageMeshData.mesh.texture = _textureCache[baseTextureUid];
                  pageMeshData.mesh.tint = this._tint;
                  newPagesMeshData.push(pageMeshData);
                  pagesMeshData[baseTextureUid] = pageMeshData;
              }
              pagesMeshData[baseTextureUid].total++;
          }
          // lets find any previously active pageMeshDatas that are no longer required for
          // the updated text (if any), removed and return them to the pool.
          for (var i = 0; i < activePagesMeshData.length; i++) {
              if (newPagesMeshData.indexOf(activePagesMeshData[i]) === -1) {
                  this.removeChild(activePagesMeshData[i].mesh);
              }
          }
          // next lets add any new meshes, that have not yet been added to this BitmapText
          // we only add if its not already a child of this BitmapObject
          for (var i = 0; i < newPagesMeshData.length; i++) {
              if (newPagesMeshData[i].mesh.parent !== this) {
                  this.addChild(newPagesMeshData[i].mesh);
              }
          }
          // active page mesh datas are set to be the new pages added.
          this._activePagesMeshData = newPagesMeshData;
          for (var i in pagesMeshData) {
              var pageMeshData = pagesMeshData[i];
              var total = pageMeshData.total;
              // lets only allocate new buffers if we can fit the new text in the current ones..
              // unless that is, we will be batching. Currently batching dose not respect the size property of mesh
              if (!(((_a = pageMeshData.indices) === null || _a === void 0 ? void 0 : _a.length) > 6 * total) || pageMeshData.vertices.length < mesh.Mesh.BATCHABLE_SIZE * 2) {
                  pageMeshData.vertices = new Float32Array(4 * 2 * total);
                  pageMeshData.uvs = new Float32Array(4 * 2 * total);
                  pageMeshData.indices = new Uint16Array(6 * total);
              }
              else {
                  var total_1 = pageMeshData.total;
                  var vertices = pageMeshData.vertices;
                  // Clear the garbage at the end of the vertices buffer. This will prevent the bounds miscalculation.
                  for (var i_1 = total_1 * 4 * 2; i_1 < vertices.length; i_1++) {
                      vertices[i_1] = 0;
                  }
              }
              // as a buffer maybe bigger than the current word, we set the size of the meshMaterial
              // to match the number of letters needed
              pageMeshData.mesh.size = 6 * total;
          }
          for (var i = 0; i < lenChars; i++) {
              var char = chars[i];
              var offset = char.position.x + (lineAlignOffsets[char.line] * (this._align === 'justify' ? char.prevSpaces : 1));
              if (this._roundPixels) {
                  offset = Math.round(offset);
              }
              var xPos = offset * scale;
              var yPos = char.position.y * scale;
              var texture = char.texture;
              var pageMesh = pagesMeshData[texture.baseTexture.uid];
              var textureFrame = texture.frame;
              var textureUvs = texture._uvs;
              var index = pageMesh.index++;
              pageMesh.indices[(index * 6) + 0] = 0 + (index * 4);
              pageMesh.indices[(index * 6) + 1] = 1 + (index * 4);
              pageMesh.indices[(index * 6) + 2] = 2 + (index * 4);
              pageMesh.indices[(index * 6) + 3] = 0 + (index * 4);
              pageMesh.indices[(index * 6) + 4] = 2 + (index * 4);
              pageMesh.indices[(index * 6) + 5] = 3 + (index * 4);
              pageMesh.vertices[(index * 8) + 0] = xPos;
              pageMesh.vertices[(index * 8) + 1] = yPos;
              pageMesh.vertices[(index * 8) + 2] = xPos + (textureFrame.width * scale);
              pageMesh.vertices[(index * 8) + 3] = yPos;
              pageMesh.vertices[(index * 8) + 4] = xPos + (textureFrame.width * scale);
              pageMesh.vertices[(index * 8) + 5] = yPos + (textureFrame.height * scale);
              pageMesh.vertices[(index * 8) + 6] = xPos;
              pageMesh.vertices[(index * 8) + 7] = yPos + (textureFrame.height * scale);
              pageMesh.uvs[(index * 8) + 0] = textureUvs.x0;
              pageMesh.uvs[(index * 8) + 1] = textureUvs.y0;
              pageMesh.uvs[(index * 8) + 2] = textureUvs.x1;
              pageMesh.uvs[(index * 8) + 3] = textureUvs.y1;
              pageMesh.uvs[(index * 8) + 4] = textureUvs.x2;
              pageMesh.uvs[(index * 8) + 5] = textureUvs.y2;
              pageMesh.uvs[(index * 8) + 6] = textureUvs.x3;
              pageMesh.uvs[(index * 8) + 7] = textureUvs.y3;
          }
          this._textWidth = maxLineWidth * scale;
          this._textHeight = (pos.y + data.lineHeight) * scale;
          for (var i in pagesMeshData) {
              var pageMeshData = pagesMeshData[i];
              // apply anchor
              if (this.anchor.x !== 0 || this.anchor.y !== 0) {
                  var vertexCount = 0;
                  var anchorOffsetX = this._textWidth * this.anchor.x;
                  var anchorOffsetY = this._textHeight * this.anchor.y;
                  for (var i_2 = 0; i_2 < pageMeshData.total; i_2++) {
                      pageMeshData.vertices[vertexCount++] -= anchorOffsetX;
                      pageMeshData.vertices[vertexCount++] -= anchorOffsetY;
                      pageMeshData.vertices[vertexCount++] -= anchorOffsetX;
                      pageMeshData.vertices[vertexCount++] -= anchorOffsetY;
                      pageMeshData.vertices[vertexCount++] -= anchorOffsetX;
                      pageMeshData.vertices[vertexCount++] -= anchorOffsetY;
                      pageMeshData.vertices[vertexCount++] -= anchorOffsetX;
                      pageMeshData.vertices[vertexCount++] -= anchorOffsetY;
                  }
              }
              this._maxLineHeight = maxLineHeight * scale;
              var vertexBuffer = pageMeshData.mesh.geometry.getBuffer('aVertexPosition');
              var textureBuffer = pageMeshData.mesh.geometry.getBuffer('aTextureCoord');
              var indexBuffer = pageMeshData.mesh.geometry.getIndex();
              vertexBuffer.data = pageMeshData.vertices;
              textureBuffer.data = pageMeshData.uvs;
              indexBuffer.data = pageMeshData.indices;
              vertexBuffer.update();
              textureBuffer.update();
              indexBuffer.update();
          }
          for (var i = 0; i < chars.length; i++) {
              charRenderDataPool.push(chars[i]);
          }
      };
      BitmapText.prototype.updateTransform = function () {
          this.validate();
          this.containerUpdateTransform();
      };
      BitmapText.prototype._render = function (renderer) {
          // Update the uniform
          var _a = BitmapFont.available[this._fontName], distanceFieldRange = _a.distanceFieldRange, distanceFieldType = _a.distanceFieldType, size = _a.size;
          if (distanceFieldType !== 'none') {
              // Inject the shader code with the correct value
              var _b = this.worldTransform, a = _b.a, b = _b.b, c = _b.c, d = _b.d;
              var dx = Math.sqrt((a * a) + (b * b));
              var dy = Math.sqrt((c * c) + (d * d));
              var worldScale = (Math.abs(dx) + Math.abs(dy)) / 2;
              var fontScale = this._fontSize / size;
              for (var _i = 0, _c = this._activePagesMeshData; _i < _c.length; _i++) {
                  var mesh = _c[_i];
                  mesh.mesh.shader.uniforms.uFWidth = worldScale * distanceFieldRange * fontScale * renderer.resolution;
              }
          }
          _super.prototype._render.call(this, renderer);
      };
      /**
       * Validates text before calling parent's getLocalBounds
       *
       * @return - The rectangular bounding area
       */
      BitmapText.prototype.getLocalBounds = function () {
          this.validate();
          return _super.prototype.getLocalBounds.call(this);
      };
      /**
       * Updates text when needed
       *
       * @private
       */
      BitmapText.prototype.validate = function () {
          if (this.dirty) {
              this.updateText();
              this.dirty = false;
          }
      };
      Object.defineProperty(BitmapText.prototype, "tint", {
          /**
           * The tint of the BitmapText object.
           *
           * @default 0xffffff
           */
          get: function () {
              return this._tint;
          },
          set: function (value) {
              if (this._tint === value)
                  { return; }
              this._tint = value;
              for (var i = 0; i < this._activePagesMeshData.length; i++) {
                  this._activePagesMeshData[i].mesh.tint = value;
              }
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "align", {
          /**
           * The alignment of the BitmapText object.
           *
           * @member {string}
           * @default 'left'
           */
          get: function () {
              return this._align;
          },
          set: function (value) {
              if (this._align !== value) {
                  this._align = value;
                  this.dirty = true;
              }
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "fontName", {
          /** The name of the BitmapFont. */
          get: function () {
              return this._fontName;
          },
          set: function (value) {
              if (!BitmapFont.available[value]) {
                  throw new Error("Missing BitmapFont \"" + value + "\"");
              }
              if (this._fontName !== value) {
                  this._fontName = value;
                  this.dirty = true;
              }
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "fontSize", {
          /** The size of the font to display. */
          get: function () {
              return this._fontSize;
          },
          set: function (value) {
              if (this._fontSize !== value) {
                  this._fontSize = value;
                  this.dirty = true;
              }
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "anchor", {
          /**
           * The anchor sets the origin point of the text.
           *
           * The default is `(0,0)`, this means the text's origin is the top left.
           *
           * Setting the anchor to `(0.5,0.5)` means the text's origin is centered.
           *
           * Setting the anchor to `(1,1)` would mean the text's origin point will be the bottom right corner.
           */
          get: function () {
              return this._anchor;
          },
          set: function (value) {
              if (typeof value === 'number') {
                  this._anchor.set(value);
              }
              else {
                  this._anchor.copyFrom(value);
              }
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "text", {
          /** The text of the BitmapText object. */
          get: function () {
              return this._text;
          },
          set: function (text) {
              text = String(text === null || text === undefined ? '' : text);
              if (this._text === text) {
                  return;
              }
              this._text = text;
              this.dirty = true;
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "maxWidth", {
          /**
           * The max width of this bitmap text in pixels. If the text provided is longer than the
           * value provided, line breaks will be automatically inserted in the last whitespace.
           * Disable by setting the value to 0.
           */
          get: function () {
              return this._maxWidth;
          },
          set: function (value) {
              if (this._maxWidth === value) {
                  return;
              }
              this._maxWidth = value;
              this.dirty = true;
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "maxLineHeight", {
          /**
           * The max line height. This is useful when trying to use the total height of the Text,
           * i.e. when trying to vertically align.
           *
           * @readonly
           */
          get: function () {
              this.validate();
              return this._maxLineHeight;
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "textWidth", {
          /**
           * The width of the overall text, different from fontSize,
           * which is defined in the style object.
           *
           * @readonly
           */
          get: function () {
              this.validate();
              return this._textWidth;
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "letterSpacing", {
          /** Additional space between characters. */
          get: function () {
              return this._letterSpacing;
          },
          set: function (value) {
              if (this._letterSpacing !== value) {
                  this._letterSpacing = value;
                  this.dirty = true;
              }
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "roundPixels", {
          /**
           * If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation.
           * Advantages can include sharper image quality (like text) and faster rendering on canvas.
           * The main disadvantage is movement of objects may appear less smooth.
           * To set the global default, change {@link PIXI.settings.ROUND_PIXELS}
           *
           * @default PIXI.settings.ROUND_PIXELS
           */
          get: function () {
              return this._roundPixels;
          },
          set: function (value) {
              if (value !== this._roundPixels) {
                  this._roundPixels = value;
                  this.dirty = true;
              }
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(BitmapText.prototype, "textHeight", {
          /**
           * The height of the overall text, different from fontSize,
           * which is defined in the style object.
           *
           * @readonly
           */
          get: function () {
              this.validate();
              return this._textHeight;
          },
          enumerable: false,
          configurable: true
      });
      BitmapText.prototype.destroy = function (options) {
          var _textureCache = this._textureCache;
          for (var id in _textureCache) {
              var texture = _textureCache[id];
              texture.destroy();
              delete _textureCache[id];
          }
          this._textureCache = null;
          _super.prototype.destroy.call(this, options);
      };
      BitmapText.styleDefaults = {
          align: 'left',
          tint: 0xFFFFFF,
          maxWidth: 0,
          letterSpacing: 0,
      };
      return BitmapText;
  }(display.Container));
  
  /**
   * {@link PIXI.Loader Loader} middleware for loading
   * bitmap-based fonts suitable for using with {@link PIXI.BitmapText}.
   *
   * @memberof PIXI
   */
  var BitmapFontLoader = /** @class */ (function () {
      function BitmapFontLoader() {
      }
      /**
       * Called when the plugin is installed.
       *
       * @see PIXI.Loader.registerPlugin
       */
      BitmapFontLoader.add = function () {
          loaders.LoaderResource.setExtensionXhrType('fnt', loaders.LoaderResource.XHR_RESPONSE_TYPE.TEXT);
      };
      /**
       * Called after a resource is loaded.
       *
       * @see PIXI.Loader.loaderMiddleware
       * @param {PIXI.LoaderResource} resource
       * @param {function} next
       */
      BitmapFontLoader.use = function (resource, next) {
          var format = autoDetectFormat(resource.data);
          // Resource was not recognised as any of the expected font data format
          if (!format) {
              next();
              return;
          }
          var baseUrl = BitmapFontLoader.getBaseUrl(this, resource);
          var data = format.parse(resource.data);
          var textures = {};
          // Handle completed, when the number of textures
          // load is the same number as references in the fnt file
          var completed = function (page) {
              textures[page.metadata.pageFile] = page.texture;
              if (Object.keys(textures).length === data.page.length) {
                  resource.bitmapFont = BitmapFont.install(data, textures, true);
                  next();
              }
          };
          for (var i = 0; i < data.page.length; ++i) {
              var pageFile = data.page[i].file;
              var url = baseUrl + pageFile;
              var exists = false;
              // incase the image is loaded outside
              // using the same loader, resource will be available
              for (var name in this.resources) {
                  var bitmapResource = this.resources[name];
                  if (bitmapResource.url === url) {
                      bitmapResource.metadata.pageFile = pageFile;
                      if (bitmapResource.texture) {
                          completed(bitmapResource);
                      }
                      else {
                          bitmapResource.onAfterMiddleware.add(completed);
                      }
                      exists = true;
                      break;
                  }
              }
              // texture is not loaded, we'll attempt to add
              // it to the load and add the texture to the list
              if (!exists) {
                  // Standard loading options for images
                  var options = {
                      crossOrigin: resource.crossOrigin,
                      loadType: loaders.LoaderResource.LOAD_TYPE.IMAGE,
                      metadata: Object.assign({ pageFile: pageFile }, resource.metadata.imageMetadata),
                      parentResource: resource,
                  };
                  this.add(url, options, completed);
              }
          }
      };
      /** Get folder path from a resource. */
      BitmapFontLoader.getBaseUrl = function (loader, resource) {
          var resUrl = !resource.isDataUrl ? BitmapFontLoader.dirname(resource.url) : '';
          if (resource.isDataUrl) {
              if (resUrl === '.') {
                  resUrl = '';
              }
              if (loader.baseUrl && resUrl) {
                  // if baseurl has a trailing slash then add one to resUrl so the replace works below
                  if (loader.baseUrl.charAt(loader.baseUrl.length - 1) === '/') {
                      resUrl += '/';
                  }
              }
          }
          // remove baseUrl from resUrl
          resUrl = resUrl.replace(loader.baseUrl, '');
          // if there is an resUrl now, it needs a trailing slash. Ensure that it does if the string isn't empty.
          if (resUrl && resUrl.charAt(resUrl.length - 1) !== '/') {
              resUrl += '/';
          }
          return resUrl;
      };
      /**
       * Replacement for NodeJS's path.dirname
       *
       * @param {string} url - Path to get directory for
       */
      BitmapFontLoader.dirname = function (url) {
          var dir = url
              .replace(/\\/g, '/') // convert windows notation to UNIX notation, URL-safe because it's a forbidden character
              .replace(/\/$/, '') // replace trailing slash
              .replace(/\/[^\/]*$/, ''); // remove everything after the last
          // File request is relative, use current directory
          if (dir === url) {
              return '.';
          }
          // Started with a slash
          else if (dir === '') {
              return '/';
          }
          return dir;
      };
      return BitmapFontLoader;
  }());
  
  exports.BitmapFont = BitmapFont;
  exports.BitmapFontData = BitmapFontData;
  exports.BitmapFontLoader = BitmapFontLoader;
  exports.BitmapText = BitmapText;
  //# sourceMappingURL=text-bitmap.js.map
  