import { _fontTables } from './font-tables';
import { _getFontEncodedString, _fontFlags, _getUnicodeForGlyph } from './font-utils';
import { _PdfMetrics } from './metrics';
import { _getDingbatsGlyphsUnicode, _getEncoding, _getFontBasicMetrics, _getFontNameToFileMap, _getGlyphMapForStandardFonts, _getGlyphsUnicode, _getNonStdFontMap, _getSerifFonts, _getStdFontMap, _getSupplementalGlyphMapForArialBlack, _getFontGlyphMap, _getSymbolsFonts, _macRomanEncoding, _standardEncoding, _symbolSetEncoding, _winAnsiEncoding, _zapfDingbatsEncoding } from './encoding-utils';
import { _PdfCharacterMapFactory, _PdfIdentityCharacterMap } from './cmap';
import { _PdfGlyphTable } from './glyph';
import { _PdfCompactFont } from './compact-font-parser';
import { _bytesToString, _PdfBaseStream, _PdfDictionary, _PdfName, _PdfNullStream, _PdfReference, _PdfStream, FormatError, PdfFontStyle } from '@syncfusion/ej2-pdf';
var _FontStructure = /** @class */ (function () {
    function _FontStructure(dictionary, crossReference) {
        this._encoding = '';
        this._composite = false;
        this._cssFontInfo = null; //eslint-disable-line
        this._charsCache = Object.create(null); //eslint-disable-line
        this._glyphCache = Object.create(null); //eslint-disable-line
        this._isSerifFont = false;
        this._isSymbolicFont = false;
        this._isType3Font = false;
        this._isInternalFont = false;
        if (dictionary) {
            this._dictionary = dictionary;
            this._crossReference = crossReference;
            this._initialize();
        }
    }
    _FontStructure.prototype._initialize = function () {
        var font = new _FontHelper(this, this._crossReference);
        font._preEvaluateFont(this._dictionary);
    };
    _FontStructure.prototype._charsToGlyphs = function (chars) {
        var glyphs; //eslint-disable-line
        var font = new _FontHelper(this, this._crossReference);
        if (this._charsCache) {
            glyphs = this._charsCache[chars]; //eslint-disable-line
        }
        if (glyphs) {
            return glyphs;
        }
        glyphs = [];
        if (this._characterMap) {
            var c = Object.create(null); //eslint-disable-line
            var ii = chars.length;
            var i = 0;
            while (i < ii) {
                this._characterMap._readCharacterCodeFromString(chars, i, c);
                var charcode = c.charcode, length_1 = c.length;
                var char = chars.substring(i, i + length_1);
                i += length_1;
                var glyph = font._charToGlyph(charcode, length_1 === 1 && chars.charCodeAt(i - 1) === 0x20);
                glyph._fontCharacter = char;
                glyphs.push(glyph);
            }
        }
        else {
            for (var i = 0, ii = chars.length; i < ii; ++i) {
                var charcode = chars.charCodeAt(i); //eslint-disable-line
                var glyph = font._charToGlyph(charcode, charcode === 0x20);
                glyph._fontCharacter = chars[Number.parseInt(i.toString(), 10)];
                glyphs.push(glyph);
            }
        }
        return (this._charsCache[chars] = glyphs); //eslint-disable-line
    };
    return _FontStructure;
}());
export { _FontStructure };
var _FontHelper = /** @class */ (function () {
    function _FontHelper(fontStructure, crossReference) {
        this._hasIncludedToUnicodeMap = false;
        this._table = new _fontTables(); //option
        this._fontIdentityMatrix = [0.001, 0, 0, 0.001, 0, 0];
        this._isOpenType = false;
        this._standardFontDataCache = new Map(); //eslint-disable-line
        this._fontFlags = { FixedPitch: 1, Serif: 2, Symbolic: 4, Script: 8, NonSymbolic: 32, Italic: 64, AllCap: 65536, SmallCap: 131072, ForceBold: 262144 }; //eslint-disable-line
        this._validTables = ['OS/2', 'cmap', 'head', 'hhea', 'hmtx', 'maxp', 'name', 'post', 'loca', 'glyf', 'fpgm', 'prep', 'cvt', 'compactFont']; //eslint-disable-line
        this._ttOpsStackDeltas = [
            0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5,
            -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1,
            1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1,
            0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2,
            0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1,
            -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1,
            -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1,
            -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2
        ];
        this._fontStructure = fontStructure;
        this._crossReference = crossReference;
    }
    _FontHelper.prototype._preEvaluateFont = function (dictionary) {
        var baseDictionary = dictionary;
        var type = dictionary.get('Subtype'); //eslint-disable-line
        this._fontStructure._composite = false;
        var firstChar;
        var lastChar;
        var descendantFonts; //eslint-disable-line
        var fontStyle = this._getFontStyle(dictionary);
        this._fontStructure._fontStyle = fontStyle;
        if (type.name === 'Type0') {
            descendantFonts = dictionary.get('DescendantFonts');
            dictionary = Array.isArray(descendantFonts) ? (descendantFonts[0] instanceof _PdfReference ?
                this._crossReference._fetch(descendantFonts[0]) : descendantFonts[0]) : descendantFonts;
            type = dictionary.get('Subtype');
            this._fontStructure._composite = true;
        }
        if (dictionary.has('FirstChar')) {
            firstChar = dictionary.get('FirstChar');
        }
        else {
            firstChar = 0;
        }
        if (dictionary.has('LastChar')) {
            lastChar = dictionary.get('LastChar');
        }
        else {
            lastChar = this._fontStructure._composite ? 0xffff : 0xff;
        }
        this._fontStructure._type = type.name;
        var descriptor; //eslint-disable-line
        var toUnicode; //eslint-disable-line
        if (dictionary.has('FontDescriptor')) {
            descriptor = dictionary.get('FontDescriptor');
        }
        if (dictionary.has('ToUnicode')) {
            toUnicode = dictionary.get('ToUnicode');
        }
        if (baseDictionary.has('ToUnicode')) {
            toUnicode = baseDictionary.get('ToUnicode');
        }
        this._translateFont(descriptor, dictionary, baseDictionary, firstChar, lastChar, toUnicode);
    };
    _FontHelper.prototype._getFontStyle = function (dictionary) {
        var fontStyle = PdfFontStyle.regular;
        if (typeof (dictionary) !== 'undefined' && dictionary.has('BaseFont')) {
            var baseFont = dictionary.get('BaseFont').name;
            if (baseFont.indexOf('-') !== -1 || baseFont.indexOf(',') !== -1) {
                var style = '';
                if (baseFont.indexOf('-') !== -1) {
                    style = baseFont.split('-')[1];
                }
                else if (baseFont.indexOf(',') !== -1) {
                    style = baseFont.split(',')[1];
                }
                style = style.replace('MT', '');
                switch (style) {
                    case 'Italic':
                    case 'Oblique':
                        fontStyle = PdfFontStyle.italic;
                        break;
                    case 'Bold':
                    case 'BoldMT':
                        fontStyle = PdfFontStyle.bold;
                        break;
                    case 'BoldItalic':
                    case 'BoldOblique':
                        fontStyle = PdfFontStyle.italic | PdfFontStyle.bold;
                        break;
                }
            }
            else {
                if (baseFont.indexOf('Bold') !== -1) {
                    fontStyle = PdfFontStyle.bold;
                }
                if (baseFont.indexOf('BoldItalic') !== -1 || baseFont.indexOf('BoldOblique') !== -1) {
                    fontStyle = PdfFontStyle.italic | PdfFontStyle.bold;
                }
                if (baseFont.indexOf('Italic') !== -1 || baseFont.indexOf('Oblique') !== -1) {
                    fontStyle = PdfFontStyle.italic;
                }
            }
        }
        return fontStyle;
    };
    _FontHelper.prototype._translateFont = function (descriptor, dictionary, baseDictionary, firstChar, lastChar, unicode) {
        var isType3Font = this._fontStructure._type === 'Type3';
        this._fontStructure._isType3Font = isType3Font;
        if (!descriptor) {
            if (isType3Font) {
                var bbox_1 = this._lookupNormalRect(dictionary.getArray('FontBBox'), [0, 0, 0, 0]);
                descriptor = new _PdfDictionary();
                descriptor.set('FontName', _PdfName.get(this._fontStructure._type));
                descriptor.set('FontBBox', bbox_1);
            }
            else {
                var baseFontName = dictionary.get('BaseFont'); //eslint-disable-line
                if (!(baseFontName instanceof _PdfName)) {
                    throw new FormatError('Base font is not specified');
                }
                baseFontName = baseFontName.name.replace(/[,_]/g, '-');
                var metrics = this._getBaseFontMetrics(baseFontName); //eslint-disable-line
                var fontNameWoStyle = baseFontName.split('-', 1)[0]; //eslint-disable-line
                var flags_1 = (this._isSerifFont(fontNameWoStyle) ? _fontFlags.Serif : 0) | (metrics.monospace ?
                    _fontFlags.FixedPitch : 0) |
                    (_getSymbolsFonts()[fontNameWoStyle] ? _fontFlags.Symbolic //eslint-disable-line
                        : _fontFlags.NonSymbolic);
                this._fontStructure._name = baseFontName;
                this._fontStructure._widths = metrics.widths;
                this._fontStructure._defaultWidth = metrics.defaultWidth;
                this._fontStructure._isType3Font = isType3Font;
                this._fontStructure._flags = flags_1;
                var widths = dictionary.get('Widths'); //eslint-disable-line
                var standardFontName = this._getStandardFontName(baseFontName); //eslint-disable-line
                var file = null; //eslint-disable-line
                if (standardFontName) {
                    file = this._fetchStandardFontData(standardFontName);
                    this._fontStructure._isInternalFont = !!file;
                }
                this._extractDataStructures(dictionary, unicode);
                if (Array.isArray(widths)) {
                    var glyphWidths = []; //eslint-disable-line
                    var j = firstChar;
                    for (var _i = 0, widths_1 = widths; _i < widths_1.length; _i++) {
                        var w = widths_1[_i];
                        if (w instanceof _PdfReference) {
                            var width = this._crossReference._fetch(w); //eslint-disable-line
                            if (typeof width === 'number') {
                                glyphWidths[Number.parseInt(j.toString(), 10)] = width;
                            }
                        }
                        else if (typeof (w) === 'number') {
                            glyphWidths[Number.parseInt(j.toString(), 10)] = w;
                        }
                        j++;
                    }
                    this._fontStructure._widths = glyphWidths;
                }
                else {
                    this._fontStructure._widths = this._buildCharCodeToWidth(metrics.widths);
                }
                this._setFontData();
                return;
            }
        }
        var fontName; //eslint-disable-line
        if (descriptor.has('FontName')) {
            fontName = descriptor.get('FontName');
            this._fontStructure._name = fontName.name;
        }
        var baseFont = dictionary.get('BaseFont'); //eslint-disable-line
        if (typeof fontName === 'string') {
            fontName = _PdfName.get(fontName);
        }
        if (typeof baseFont === 'string') {
            baseFont = _PdfName.get(baseFont);
        }
        if (!fontName) {
            fontName = baseFont;
        }
        if (!(fontName instanceof _PdfName)) {
            throw new FormatError('invalid font name');
        }
        var fontFile; //eslint-disable-line
        var length1;
        var length2;
        var length3;
        try {
            if (descriptor.has('FontFile')) {
                fontFile = descriptor.get('FontFile');
            }
            else if (descriptor.has('FontFile2')) {
                fontFile = descriptor.get('FontFile2');
            }
            else if (descriptor.has('FontFile3')) {
                fontFile = descriptor.get('FontFile3');
            }
        }
        catch (ex) {
            fontFile = new _PdfNullStream();
        }
        if (fontFile) {
            if (fontFile.dictionary) {
                var subtypeEntry = fontFile.dictionary.get('Subtype'); //eslint-disable-line
                if (subtypeEntry instanceof _PdfName) {
                    this._fontStructure._subtype = subtypeEntry.name;
                }
                length1 = fontFile.dictionary.get('Length1');
                length2 = fontFile.dictionary.get('Length2');
                length3 = fontFile.dictionary.get('Length3');
                this._fontStructure._length1 = length1;
                this._fontStructure._length2 = length2;
                this._fontStructure._length3 = length3;
                this._file = fontFile;
            }
        }
        else if (!isType3Font) {
            var standardFontName = this._getStandardFontName(fontName.name); //eslint-disable-line
            if (standardFontName) {
                fontFile = this._fetchStandardFontData(standardFontName);
                this._fontStructure._isInternalFont = !!fontFile;
                this._file = fontFile;
            }
        }
        var fontMatrix = this._lookupMatrix(dictionary.getArray('FontMatrix'), this._fontIdentityMatrix);
        var bbox = this._lookupNormalRect(descriptor.getArray('FontBBox') || dictionary.getArray('FontBBox'), undefined);
        var ascent;
        var descent;
        var capHeight;
        var flags;
        if (descriptor.has('Ascent')) {
            ascent = descriptor.get('Ascent');
        }
        if (descriptor.has('Descent')) {
            descent = descriptor.get('Descent');
        }
        if (descriptor.has('CapHeight')) {
            capHeight = descriptor.get('CapHeight');
        }
        if (descriptor.has('FontName')) {
            this._fontStructure._name = descriptor.get('FontName').name;
        }
        if (descriptor.has('Flags')) {
            flags = descriptor.get('Flags');
        }
        var glyphSpaceUnits = 1000;
        this._fontStructure._fontMatrix = fontMatrix;
        this._fontStructure._boundingBox = bbox;
        this._firstChar = firstChar;
        this._lastChar = lastChar;
        this._fontStructure._ascent = ascent / glyphSpaceUnits;
        this._fontStructure._descent = descent / glyphSpaceUnits;
        this._fontStructure._lineHeight = this._fontStructure._ascent - this._fontStructure._descent;
        this._fontStructure._flags = flags;
        var encoding;
        if (baseDictionary.has('Encoding')) {
            var cidEncoding = baseDictionary.get('Encoding'); //eslint-disable-line
            if (cidEncoding instanceof _PdfName) {
                encoding = cidEncoding;
                this._fontStructure._encoding = encoding.name;
            }
            else if (cidEncoding instanceof _PdfDictionary && cidEncoding.has('Type')) {
                this._fontStructure._encoding = cidEncoding.get('Type').name;
            }
        }
        if (this._fontStructure._composite) {
            var map = new _PdfCharacterMapFactory();
            var cMap = map._create(encoding, null, null); //eslint-disable-line
            this._fontStructure._characterMap = cMap;
            this._fontStructure._vertical = this._fontStructure._characterMap._vertical;
        }
        this._extractDataStructures(dictionary, unicode);
        this._extractWidths(dictionary, flags, firstChar, descriptor);
        this._setFontData();
        this._fontStructure._capHeight = capHeight / glyphSpaceUnits;
    };
    _FontHelper.prototype._buildCharCodeToWidth = function (widthsByGlyphName) {
        var widths = Object.create(null); //eslint-disable-line
        var differences = this._fontStructure._differences; //eslint-disable-line
        var encoding = this._fontStructure._defaultEncoding; //eslint-disable-line
        for (var charCode = 0; charCode < 256; charCode++) { //eslint-disable-line
            if (charCode in differences && widthsByGlyphName[differences[charCode]]) { //eslint-disable-line
                widths[charCode] = widthsByGlyphName[differences[charCode]]; //eslint-disable-line
                continue;
            }
            if (charCode in encoding && widthsByGlyphName[encoding[charCode]]) { //eslint-disable-line
                widths[charCode] = widthsByGlyphName[encoding[charCode]]; //eslint-disable-line
                continue;
            }
        }
        return widths;
    };
    _FontHelper.prototype._fetchStandardFontData = function (name) {
        var cachedData = this._standardFontDataCache.get(name); //eslint-disable-line
        if (cachedData) {
            return new _PdfStream(cachedData);
        }
        if (name !== 'Symbol' && name !== 'ZapfDingbats') {
            return null;
        }
        var standardFontNameToFileName = _getFontNameToFileMap; //eslint-disable-line
        var filename = standardFontNameToFileName[name]; //eslint-disable-line
        var cleanBase64 = _getFontEncodedString(filename).replace(/^data:.+;base64,/, '');
        var binaryString = atob(cleanBase64);
        var len = binaryString.length;
        var bytes = new Uint8Array(len);
        for (var i = 0; i < len; i++) {
            bytes[Number.parseInt(i.toString(), 10)] = binaryString.charCodeAt(i);
        }
        this._file = new _PdfStream(bytes);
        return this._file;
    };
    _FontHelper.prototype._setFontData = function () {
        if (this._fontStructure._type === 'Type3') {
            this._fontStructure._toFontChar = [];
            for (var charCode = 0; charCode < 256; charCode++) {
                this._fontStructure._toFontChar[Number.parseInt(charCode.toString(), 10)] =
                    this._fontStructure._differences[Number.parseInt(charCode.toString(), 10)] ||
                        this._fontStructure._defaultEncoding[Number.parseInt(charCode.toString(), 10)];
            }
            return;
        }
        if (!this._file) {
            this._setFallBackSystemFont(this);
            return;
        }
        this._getFontFileType();
        var compactFont; //eslint-disable-line
        try {
            switch (this._fileType) {
                case 'MMType1':
                case 'Type1':
                case 'CIDFontType0':
                    this._fontStructure._mimeType = 'font/opentype';
                    if (this._fileSubtype === 'Type1C' || this._fileSubtype === 'CIDFontType0C') {
                        compactFont = new _PdfCompactFont(this._file, this);
                        if (compactFont._builtInEncoding) {
                            this._fontStructure._builtInEncoding = compactFont._builtInEncoding;
                        }
                    }
                    this._adjustWidths();
                    if (this._fontStructure._builtInEncoding) {
                        this._adjustType1ToUnicode();
                    }
                    break;
                case 'OpenType':
                case 'TrueType':
                case 'CIDFontType2':
                    this._fontStructure._mimeType = 'font/opentype';
                    this._checkAndRepair(this._file);
                    if (this._isOpenType) {
                        this._adjustWidths();
                        this._fontStructure._type = 'OpenType';
                    }
                    break;
                default:
                    throw new FormatError('Font  is not supported');
            }
        }
        catch (e) {
            this._setFallBackSystemFont(this);
            return;
        }
        this._amendFallBackToUnicodeMap(this);
        this._fontStructure._subtype = this._fileSubtype;
    };
    _FontHelper.prototype._isTrueTypeFile = function (file) {
        var header = file.peekBytes(4); //eslint-disable-line
        return (this._readUnsignedInt32(header, 0) === 0x00010000 || _bytesToString(header) === 'true');
    };
    _FontHelper.prototype._readUnsignedInt32 = function (data, offset) {
        return (((data[Number.parseInt(offset.toString(), 10)] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8)
            | data[offset + 3]) >>> 0);
    };
    _FontHelper.prototype._isOpenTypeFile = function (file) {
        var header = file.peekBytes(4); //eslint-disable-line
        return _bytesToString(header) === 'OTTO';
    };
    _FontHelper.prototype._isType1File = function (file) {
        var header = file.peekBytes(2); //eslint-disable-line
        if (header[0] === 0x25 && header[1] === 0x21) {
            return true;
        }
        if (header[0] === 0x80 && header[1] === 0x01) {
            return true;
        }
        return false;
    };
    _FontHelper.prototype._isCompactFontFile = function (file) {
        var header = file.peekBytes(4); //eslint-disable-line
        if (header[0] >= 1 && header[3] >= 1 && header[3] <= 4) {
            return true;
        }
        return false;
    };
    _FontHelper.prototype._getFontFileType = function () {
        var composite = this._fontStructure._composite;
        var type = this._fontStructure._type;
        var subtype = this._fontStructure._subtype;
        if (this._isTrueTypeFile(this._file) || this._isTrueTypeCollectionFile(this._file)) {
            this._fileType = composite ? 'CIDFontType2' : 'TrueType';
        }
        else if (this._isOpenTypeFile(this._file)) {
            this._fileType = composite ? 'CIDFontType2' : 'OpenType';
        }
        else if (this._isType1File(this._file)) {
            if (composite) {
                this._fileType = 'CIDFontType0';
            }
            else {
                this._fileType = type === 'MMType1' ? 'MMType1' : 'Type1';
            }
        }
        else if (this._isCompactFontFile(this._file)) {
            if (composite) {
                this._fileType = 'CIDFontType0';
                this._fileSubtype = 'CIDFontType0C';
            }
            else {
                this._fileType = type === 'MMType1' ? 'MMType1' : 'Type1';
                this._fileSubtype = 'Type1C';
            }
        }
        else {
            this._fileType = type;
            this._fileSubtype = subtype;
        }
    };
    _FontHelper.prototype._extractWidths = function (descriptor, flags, firstChar, dictionary) {
        var glyphsWidths = []; //eslint-disable-line
        var defaultWidth = 0;
        var glyphsVMetrics = []; //eslint-disable-line
        var defaultVMetrics; //eslint-disable-line
        if (this._fontStructure._composite) {
            var dw = descriptor.get('DW'); //eslint-disable-line
            defaultWidth = typeof dw === 'number' ? Math.ceil(dw) : 1000;
            var widths = descriptor.get('W'); //eslint-disable-line
            if (Array.isArray(widths)) {
                for (var i = 0, ii = widths.length; i < ii; i++) {
                    var start = void 0; //eslint-disable-line
                    if (widths[Number.parseInt(i.toString(), 10)] instanceof _PdfReference) {
                        start = this._crossReference._fetch(widths[i++]);
                    }
                    else {
                        start = widths[i++];
                    }
                    if (!Number.isInteger(start)) {
                        break;
                    }
                    var code = widths[Number.parseInt(i.toString(), 10)]; //eslint-disable-line
                    if (code instanceof _PdfReference) {
                        code = this._crossReference._fetch(widths[Number.parseInt(i.toString(), 10)]);
                    }
                    if (Array.isArray(code)) {
                        for (var _i = 0, code_1 = code; _i < code_1.length; _i++) {
                            var c = code_1[_i];
                            var width = void 0; //eslint-disable-line
                            if (c instanceof _PdfReference) {
                                width = this._crossReference._fetch(c);
                            }
                            else {
                                width = c;
                            }
                            if (typeof width === 'number') {
                                glyphsWidths[Number.parseInt(start.toString(), 10)] = width;
                            }
                            start++;
                        }
                    }
                    else if (Number.isInteger(code)) {
                        var width = void 0; //eslint-disable-line
                        var widthValue = widths[++i]; //eslint-disable-line
                        if (widthValue instanceof _PdfReference) {
                            width = this._crossReference._fetch(widthValue);
                        }
                        else {
                            width = widthValue;
                        }
                        if (typeof width !== 'number') {
                            continue;
                        }
                        for (var j = start; j <= code; j++) {
                            glyphsWidths[Number.parseInt(j.toString(), 10)] = width;
                        }
                    }
                    else {
                        break;
                    }
                }
            }
            if (this._vertical) {
                var dw2 = descriptor.getArray('DW2'); //eslint-disable-line
                var vmetrics = this._isNumberArray(dw2, 2) ? dw2 : [880, -1000]; //eslint-disable-line
                vmetrics = descriptor.get('W2');
                if (Array.isArray(vmetrics)) {
                    for (var i = 0, ii = vmetrics.length; i < ii; i++) {
                        var start = this._crossReference._fetch(vmetrics[i++]); //eslint-disable-line
                        if (!Number.isInteger(start)) {
                            break;
                        }
                        var code = this._crossReference._fetch(vmetrics[Number.parseInt(i.toString(), 10)]);
                        if (Array.isArray(code)) {
                            for (var j = 0, jj = code.length; j < jj; j++) {
                                var vmetric = [this._crossReference._fetch(code[j++]), this._crossReference._fetch(code[j++]),
                                    this._crossReference._fetch(code[Number.parseInt(j.toString(), 10)])];
                                if (this._isNumberArray(vmetric, null)) {
                                    glyphsVMetrics[Number.parseInt(start.toString(), 10)] = vmetric;
                                }
                                start++;
                            }
                        }
                        else if (Number.isInteger(code)) {
                            var vmetric = [this._crossReference._fetch(vmetrics[++i]), this._crossReference._fetch(vmetrics[++i]),
                                this._crossReference._fetch(vmetrics[++i])];
                            if (!this._isNumberArray(vmetric, null)) {
                                continue;
                            }
                            for (var j = start; j <= code; j++) {
                                glyphsVMetrics[Number.parseInt(j.toString(), 10)] = vmetric;
                            }
                        }
                        else {
                            break;
                        }
                    }
                }
            }
        }
        else {
            var widths = descriptor.get('Widths'); //eslint-disable-line
            if (Array.isArray(widths)) {
                var j = firstChar;
                for (var _a = 0, widths_2 = widths; _a < widths_2.length; _a++) {
                    var w = widths_2[_a];
                    var width = void 0; //eslint-disable-line 
                    if (w instanceof _PdfReference) {
                        width = this._crossReference._fetch(w);
                    }
                    else {
                        width = w;
                    }
                    if (typeof width === 'number') {
                        glyphsWidths[Number.parseInt(j.toString(), 10)] = width;
                    }
                    j++;
                }
                var missingWidth = dictionary.get('MissingWidth'); //eslint-disable-line
                defaultWidth = typeof missingWidth === 'number' ? missingWidth : 0;
            }
        }
        var isMonospace = true;
        var firstWidth = defaultWidth; //eslint-disable-line
        var keys = Object.keys(glyphsWidths); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var glyph = keys[i]; //eslint-disable-line
            var glyphWidth = glyphsWidths[glyph]; //eslint-disable-line
            if (!glyphWidth) {
                continue;
            }
            if (!firstWidth) {
                firstWidth = glyphWidth;
                continue;
            }
            if (firstWidth !== glyphWidth) {
                isMonospace = false;
                break;
            }
        }
        if (isMonospace) {
            flags |= this._fontFlags.FixedPitch;
        }
        else {
            flags &= ~this._fontFlags.FixedPitch;
        }
        this._fontStructure._defaultWidth = defaultWidth;
        this._fontStructure._widths = glyphsWidths;
        this._flags = flags;
    };
    _FontHelper.prototype._normalizeRect = function (rect) {
        var r = rect.slice(0); // clone rect
        if (rect[0] > rect[2]) {
            r[0] = rect[2];
            r[2] = rect[0];
        }
        if (rect[1] > rect[3]) {
            r[1] = rect[3];
            r[3] = rect[1];
        }
        return r;
    };
    _FontHelper.prototype._isNumberArray = function (arr, len) {
        if (!Array.isArray(arr)) {
            return false;
        }
        if (len !== null && arr.length !== len) {
            return false;
        }
        for (var i = 0; i < arr.length; i++) {
            if (typeof arr[Number.parseInt(i.toString(), 10)] !== 'number') {
                return false;
            }
        }
        return true;
    };
    _FontHelper.prototype._lookupMatrix = function (arr, fallBack) {
        return this._isNumberArray(arr, 6) ? arr : fallBack;
    };
    _FontHelper.prototype._lookupRect = function (arr, fallBack) {
        return this._isNumberArray(arr, 4) ? arr : fallBack;
    };
    _FontHelper.prototype._lookupNormalRect = function (arr, fallBack) {
        return this._isNumberArray(arr, 4) ? this._normalizeRect(arr) : fallBack;
    };
    _FontHelper.prototype._extractDataStructures = function (dictionary, unicode) {
        var differences = []; //eslint-disable-line
        var baseEncodingName = null; //eslint-disable-line
        var encoding; //eslint-disable-line
        if (this._fontStructure._composite) {
            var cidSystemInfo = dictionary.get('CIDSystemInfo'); //eslint-disable-line
            if (cidSystemInfo instanceof _PdfDictionary) {
                this._fontStructure._characterSystemInfo = {
                    registry: this._stringToPdfString(cidSystemInfo.get('Registry')),
                    ordering: this._stringToPdfString(cidSystemInfo.get('Ordering')),
                    supplement: cidSystemInfo.get('Supplement')
                };
            }
        }
        if (dictionary.has('Encoding')) {
            encoding = dictionary.get('Encoding');
            if (encoding instanceof _PdfDictionary) {
                baseEncodingName = encoding.get('BaseEncoding');
                baseEncodingName = baseEncodingName instanceof _PdfName ? baseEncodingName.name : null;
                if (encoding.has('Differences')) {
                    var diffEncoding = encoding.get('Differences'); //eslint-disable-line
                    var index = 0;
                    for (var _i = 0, diffEncoding_1 = diffEncoding; _i < diffEncoding_1.length; _i++) {
                        var entry = diffEncoding_1[_i];
                        var data = void 0; //eslint-disable-line
                        if (entry instanceof _PdfReference) {
                            data = this._crossReference._fetch(entry);
                        }
                        else {
                            data = entry;
                        }
                        if (typeof data === 'number') {
                            index = data;
                        }
                        else if (data instanceof _PdfName) {
                            differences[index++] = data.name;
                        }
                        else {
                            throw new FormatError("Invalid entry in 'Differences' array: " + data);
                        }
                    }
                }
            }
            else if (encoding instanceof _PdfName) {
                baseEncodingName = encoding.name;
            }
            if (baseEncodingName !== 'MacRomanEncoding' && baseEncodingName !== 'MacExpertEncoding' && baseEncodingName !== 'WinAnsiEncoding') {
                baseEncodingName = null;
            }
        }
        var nonEmbeddedFont = !this._file || this._fontStructure._isInternalFont; //eslint-disable-line
        var isSymbolsFontName = _getSymbolsFonts()[this._fontStructure._name]; //eslint-disable-line
        if (baseEncodingName && nonEmbeddedFont && isSymbolsFontName) {
            baseEncodingName = null;
        }
        if (baseEncodingName) {
            this._fontStructure._defaultEncoding = _getEncoding(baseEncodingName);
        }
        else {
            var isSymbolicFont = !!(this._fontStructure._flags & this._fontFlags.Symbolic);
            var isNonSymbolicFont = !!(this._fontStructure._flags & this._fontFlags.NonSymbolic);
            encoding = _standardEncoding;
            if (this._fontStructure._type === 'TrueType' && !isNonSymbolicFont) {
                encoding = _winAnsiEncoding;
            }
            if (isSymbolicFont) {
                encoding = _macRomanEncoding;
                if (nonEmbeddedFont) {
                    if (/Symbol/i.test(this._fontStructure._name)) {
                        encoding = _symbolSetEncoding;
                    }
                    else if (/Dingbats/i.test(this._fontStructure._name)) {
                        encoding = _zapfDingbatsEncoding;
                    }
                    else if (/Wingdings/i.test(this._fontStructure._name)) {
                        encoding = _winAnsiEncoding;
                    }
                }
            }
            this._fontStructure._defaultEncoding = encoding;
        }
        this._fontStructure._differences = differences;
        this._baseEncodingName = baseEncodingName;
        this._fontStructure._toUnicode = this._readToUnicode(unicode);
        this._hasEncoding = !!baseEncodingName || differences.length > 0;
        this._fontStructure._toUnicode = this._buildToUnicode(baseEncodingName, this._hasEncoding, this._fontStructure._toUnicode);
    };
    _FontHelper.prototype._stringToPdfString = function (text) {
        if (text[0] >= '\xEF') {
            var encoding = void 0; //eslint-disable-line
            if (text[0] === '\xFE' && text[1] === '\xFF') {
                encoding = 'utf-16be';
                if (text.length % 2 === 1) {
                    text = text.slice(0, -1);
                }
            }
            else if (text[0] === '\xFF' && text[1] === '\xFE') {
                encoding = 'utf-16le';
                if (text.length % 2 === 1) {
                    text = text.slice(0, -1);
                }
            }
            else if (text[0] === '\xEF' && text[1] === '\xBB' && text[2] === '\xBF') {
                encoding = 'utf-8';
            }
            if (encoding) {
                try {
                    var decoder = new TextDecoder(encoding, { fatal: true });
                    var buffer = this._stringToBytes(text);
                    var decoded = decoder.decode(buffer);
                    if (!decoded.includes('\x1b')) {
                        return decoded;
                    }
                    return decoded.replace(/[\x1b][^\x1b]*(?:[\x1b]|$)/g, ''); //eslint-disable-line
                }
                catch (ex) {
                    throw new FormatError(ex.toString());
                }
            }
        }
        var strBuf = []; //eslint-disable-line
        var stringTranslateTable = [
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2d8,
            0x2c7, 0x2c6, 0x2d9, 0x2dd, 0x2db, 0x2da, 0x2dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x192,
            0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018,
            0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x141, 0x152, 0x160, 0x178, 0x17d,
            0x131, 0x142, 0x153, 0x161, 0x17e, 0, 0x20ac
        ];
        for (var i = 0, ii = text.length; i < ii; i++) {
            var charCode = text.charCodeAt(i); //eslint-disable-line
            var code = stringTranslateTable[charCode]; //eslint-disable-line
            strBuf.push(code ? String.fromCharCode(code) : text.charAt(i));
        }
        return strBuf.join('');
    };
    _FontHelper.prototype._readToUnicode = function (cmapObj) {
        var cMap = new _PdfCharacterMapFactory();
        if (!cmapObj) {
            return null;
        }
        if (cmapObj instanceof _PdfName) {
            var cmap = cMap._create(cmapObj, null, null); //eslint-disable-line
            if (cmap instanceof _PdfIdentityCharacterMap) {
                return new _PdfIdentityToUnicodeMap(0, 0xffff);
            }
            return new _UnicodeMap(cmap.getMap());
        }
        if (cmapObj instanceof _PdfBaseStream) {
            var cmap = cMap._create(cmapObj, null, null); //eslint-disable-line
            if (cmap) {
                try {
                    if (cmap instanceof _PdfIdentityCharacterMap) {
                        return new _PdfIdentityToUnicodeMap(0, 0xffff);
                    }
                    var map_1 = new Array(cmap._map.length); //eslint-disable-line
                    cmap._forEach(function (charCode, token) {
                        if (typeof token === 'number') {
                            map_1[Number.parseInt(charCode.toString(), 10)] = String.fromCodePoint(token);
                            return;
                        }
                        if (token.length % 2 !== 0) {
                            token = '\u0000' + token;
                        }
                        var str = [];
                        for (var k = 0; k < token.length; k += 2) {
                            var w1 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1);
                            if ((w1 & 0xf800) !== 0xd800) {
                                str.push(w1);
                                continue;
                            }
                            k += 2;
                            var w2 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1); //eslint-disable-line
                            str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000);
                        }
                        map_1[charCode] = String.fromCodePoint.apply(String, str); //eslint-disable-line
                    });
                    return new _UnicodeMap(map_1);
                }
                catch (reason) {
                    throw new FormatError(reason.toString());
                }
            }
        }
        return null;
    };
    _FontHelper.prototype._buildToUnicode = function (baseEncodingName, isEncoding, toUnicode) {
        this._hasIncludedToUnicodeMap = toUnicode && toUnicode._length > 0;
        if (this._hasIncludedToUnicodeMap) {
            if (!this._fontStructure._composite && isEncoding) {
                this._fallBackToUnicodeMap = this._simpleFontToUnicode(baseEncodingName);
            }
            return toUnicode;
        }
        if (!this._fontStructure._composite) {
            return new _UnicodeMap(this._simpleFontToUnicode(this._baseEncodingName));
        }
        if (this._fontStructure._composite && ((this._fontStructure._characterMap.builtInCMap &&
            !(this._fontStructure._characterMap instanceof _PdfIdentityCharacterMap)) ||
            (this._fontStructure._characterSystemInfo && this._fontStructure._characterSystemInfo.registry === 'Adobe' &&
                (this._fontStructure._characterSystemInfo.ordering === 'GB1' || this._fontStructure._characterSystemInfo.ordering === 'CNS1' ||
                    this._fontStructure._characterSystemInfo.ordering === 'Japan1' || this._fontStructure._characterSystemInfo.ordering === 'Korea1')))) {
            var _a = this._fontStructure._characterSystemInfo, registry = _a.registry, ordering = _a.ordering;
            var ucs2CMapName = _PdfName.get(registry + "-" + ordering + "-UCS2"); //eslint-disable-line
            var map = new _PdfCharacterMapFactory();
            var ucs2CMap_1 = map._create(ucs2CMapName, null, null); //eslint-disable-line
            var toUnicode_1 = []; //eslint-disable-line
            var buf_1 = []; //eslint-disable-line
            this._fontStructure._characterMap._forEach(function (charcode, cid) {
                if (cid > 0xffff) {
                    throw new FormatError('Max size of Character identifier is 65,535');
                }
                var ucs2 = ucs2CMap_1._lookup(cid); //eslint-disable-line
                if (ucs2) {
                    buf_1.length = 0;
                    for (var i = 0, ii = ucs2.length; i < ii; i += 2) {
                        buf_1.push((ucs2.charCodeAt(i) << 8) + ucs2.charCodeAt(i + 1));
                    }
                    toUnicode_1[charcode] = String.fromCharCode.apply(String, buf_1); //eslint-disable-line
                }
            });
            return new _UnicodeMap(toUnicode_1);
        }
        return new _PdfIdentityToUnicodeMap(this._firstChar, this._lastChar);
    };
    _FontHelper.prototype._simpleFontToUnicode = function (baseEncodingName, forceGlyphs) {
        if (forceGlyphs === void 0) { forceGlyphs = false; }
        var toUnicode = []; //eslint-disable-line
        var encoding = this._fontStructure._defaultEncoding.slice(); //eslint-disable-line
        var differences = this._fontStructure._differences; //eslint-disable-line
        var keys = Object.keys(differences); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var charCode = keys[i]; //eslint-disable-line
            var glyphName = differences[Number.parseInt(charCode.toString(), 10)];
            if (glyphName === '.notdef') {
                continue;
            }
            encoding[Number.parseInt(charCode.toString(), 10)] = glyphName;
        }
        var glyphsUnicodeMap = _getGlyphsUnicode(); //eslint-disable-line
        keys = Object.keys(encoding);
        for (var i = 0; i < keys.length; i++) {
            var charcode = keys[i]; //eslint-disable-line
            var glyphName = encoding[Number.parseInt(charcode.toString(), 10)]; //eslint-disable-line
            if (glyphName === '') {
                continue;
            }
            var unicode = glyphsUnicodeMap[glyphName]; //eslint-disable-line 
            if (unicode !== undefined) {
                toUnicode[Number.parseInt(charcode.toString(), 10)] = String.fromCharCode(unicode);
                continue;
            }
            var code = 0;
            switch (glyphName[0]) {
                case 'G':
                    if (glyphName.length === 3) {
                        code = parseInt(glyphName.substring(1), 16);
                    }
                    break;
                case 'g':
                    if (glyphName.length === 5) {
                        code = parseInt(glyphName.substring(1), 16);
                    }
                    break;
                case 'C':
                case 'c':
                    if (glyphName.length >= 3 && glyphName.length <= 4) {
                        var codeStr = glyphName.substring(1); //eslint-disable-line
                        if (forceGlyphs) {
                            code = parseInt(codeStr, 16);
                            break;
                        }
                        code = +codeStr;
                        if (Number.isNaN(code) && Number.isInteger(parseInt(codeStr, 16))) {
                            return this._simpleFontToUnicode(true);
                        }
                    }
                    break;
                case 'u':
                    unicode = _getUnicodeForGlyph(glyphName, glyphsUnicodeMap);
                    if (unicode !== -1) {
                        code = unicode;
                    }
                    break;
                default:
                    switch (glyphName) {
                        case 'f_h':
                        case 'f_t':
                        case 'T_h':
                            toUnicode[Number.parseInt(charcode.toString(), 10)] = glyphName.replace('_', '');
                            continue;
                    }
                    break;
            }
            if (code > 0 && code <= 0x10ffff && Number.isInteger(code)) {
                if (baseEncodingName && code === +charcode) {
                    var baseEncoding = _getEncoding(baseEncodingName); //eslint-disable-line
                    glyphName = baseEncoding[Number.parseInt(charcode.toString(), 10)];
                    if (baseEncoding && glyphName) {
                        toUnicode[Number.parseInt(charcode.toString(), 10)] =
                            String.fromCharCode(glyphsUnicodeMap[Number.parseInt(glyphName.toString(), 10)]);
                        continue;
                    }
                }
                toUnicode[Number.parseInt(charcode.toString(), 10)] = String.fromCodePoint(code);
            }
        }
        return toUnicode;
    };
    _FontHelper.prototype._string32 = function (value) {
        return String.fromCharCode((value >> 24) & 0xff, (value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff);
    };
    _FontHelper.prototype._buildToFontChar = function (encoding, glyphsUnicodeMap, differences) {
        var toFontChar = []; //eslint-disable-line
        var unicode; //eslint-disable-line
        for (var i = 0, ii = encoding.length; i < ii; i++) {
            unicode = this._getUnicodeForGlyph(encoding[Number.parseInt(i.toString(), 10)], glyphsUnicodeMap);
            if (unicode !== -1) {
                toFontChar[Number.parseInt(i.toString(), 10)] = unicode;
            }
        }
        var keys = Object.keys(differences); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var charCode = keys[i]; //eslint-disable-line
            unicode = this._getUnicodeForGlyph(differences[Number.parseInt(charCode.toString(), 10)], glyphsUnicodeMap);
            if (unicode !== -1) {
                toFontChar[+charCode] = unicode;
            }
        }
        return toFontChar;
    };
    _FontHelper.prototype._getUnicodeForGlyph = function (name, glyphsUnicodeMap) {
        var unicode = glyphsUnicodeMap[Number.parseInt(name.toString(), 10)]; //eslint-disable-line
        if (unicode !== undefined) {
            return unicode;
        }
        if (!name) {
            return -1;
        }
        if (name[0] === 'u') {
            var nameLen = name.length;
            var hexStr = void 0;
            if (nameLen === 7 && name[1] === 'n' && name[2] === 'i') {
                hexStr = name.substring(3);
            }
            else if (nameLen >= 5 && nameLen <= 7) {
                hexStr = name.substring(1);
            }
            else {
                return -1;
            }
            if (hexStr === hexStr.toUpperCase()) {
                unicode = parseInt(hexStr, 16);
                if (unicode >= 0) {
                    return unicode;
                }
            }
        }
        return -1;
    };
    _FontHelper.prototype._writeUnSignedInt32 = function (bytes, index, value) {
        bytes[index + 3] = value & 0xff;
        bytes[index + 2] = value >>> 8;
        bytes[index + 1] = value >>> 16;
        bytes[Number.parseInt(index.toString(), 10)] = value >>> 24;
    };
    _FontHelper.prototype._stringToBytes = function (value) {
        if (typeof value !== 'string') {
            //unreachable('Invalid argument for stringToBytes');
        }
        var length = value.length;
        var bytes = new Uint8Array(length);
        for (var i = 0; i < length; ++i) {
            bytes[Number.parseInt(i.toString(), 10)] = value.charCodeAt(i) & 0xff;
        }
        return bytes;
    };
    _FontHelper.prototype._writeSignedInt16 = function (bytes, index, value) {
        bytes[index + 1] = value;
        bytes[Number.parseInt(index.toString(), 10)] = value >>> 8;
    };
    _FontHelper.prototype._signedInt16 = function (b0, b1) {
        var value = (b0 << 8) + b1;
        return value & (1 << 15) ? value - 0x10000 : value;
    };
    _FontHelper.prototype._isSerifFont = function (baseFontName) {
        var fontNameWoStyle = baseFontName.split('-', 1)[0]; //eslint-disable-line
        return (fontNameWoStyle in _getSerifFonts() || /serif/gi.test(fontNameWoStyle));
    };
    _FontHelper.prototype._adjustWidths = function () {
        if (!this._fontStructure._fontMatrix[0]) {
            return;
        }
        if (this._fontStructure._fontMatrix[0] === this._fontIdentityMatrix[0]) {
            return;
        }
        var scale = 0.001 / this._fontStructure._fontMatrix[0];
        var glyphsWidths = this._fontStructure._widths; //eslint-disable-line
        var keys = Object.keys(glyphsWidths); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var glyph = keys[i]; //eslint-disable-line
            glyphsWidths[Number.parseInt(glyph.toString(), 10)] *= scale;
        }
        this._fontStructure._defaultWidth *= scale;
    };
    _FontHelper.prototype._getBaseFontMetrics = function (name) {
        var defaultWidth = 0;
        var widths = Object.create(null); //eslint-disable-line
        var monospace = false;
        var stdFontMap = _getStdFontMap(); //eslint-disable-line
        var lookupName = stdFontMap[Number.parseInt(name.toString(), 10)] || name;
        var metrices = this._getMetrics(); //eslint-disable-line
        if (metrices.indexOf(lookupName) === -1) {
            lookupName = this._isSerifFont(name) ? 'Times-Roman' : 'Helvetica';
        }
        var metrics = new _PdfMetrics();
        var glyphWidths; //eslint-disable-line
        switch (lookupName) {
            case 'Courier':
                glyphWidths = metrics._courier;
                break;
            case 'Courier-Bold':
                glyphWidths = metrics._courierBold;
                break;
            case 'Courier-BoldOblique':
                glyphWidths = metrics._courierBoldOblique;
                break;
            case 'Courier-Oblique':
                glyphWidths = metrics._courierOblique;
                break;
            case 'Helvetica':
                glyphWidths = metrics._helveticaWidths;
                break;
            case 'Helvetica-Bold':
                glyphWidths = metrics._helveticaBold;
                break;
            case 'Helvetica-BoldOblique':
                glyphWidths = metrics._helveticaBoldOblique;
                break;
            case 'Helvetica-Oblique':
                glyphWidths = metrics._helveticaOblique;
                break;
            case 'Symbol':
                glyphWidths = metrics._symbol;
                break;
            case 'Times-Roman':
                glyphWidths = metrics._timesRoman;
                break;
            case 'Times-Bold':
                glyphWidths = metrics._timesBold;
                break;
            case 'Times-BoldItalic':
                glyphWidths = metrics._timesBoldItalic;
                break;
            case 'Times-Italic':
                glyphWidths = metrics._timesItalic;
                break;
            case 'ZapfDingbats':
                glyphWidths = metrics._zapfDingbats;
                break;
        }
        if (typeof glyphWidths === 'number') {
            defaultWidth = glyphWidths;
            monospace = true;
        }
        else {
            widths = glyphWidths;
        }
        return { defaultWidth: defaultWidth, monospace: monospace, widths: widths };
    };
    _FontHelper.prototype._getMetrics = function () {
        var fontNames = ['Courier', 'Courier-Bold', 'Courier-BoldOblique', 'Courier-Oblique', 'Helvetica', 'Helvetica-Bold', 'Helvetica-BoldOblique', 'Helvetica-Oblique', 'Symbol', 'Times-Bold', 'Times-Roman', 'Times-BoldItalic', 'Times-Italic', 'ZapfDingbats']; //eslint-disable-line
        return fontNames;
    };
    _FontHelper.prototype._getStandardFontName = function (name) {
        var fontName = this._normalizeFontName(name);
        var stdFontMap = _getStdFontMap(); //eslint-disable-line
        return stdFontMap[fontName]; //eslint-disable-line
    };
    _FontHelper.prototype._normalizeFontName = function (name) {
        return name.replace(/[,_]/g, '-').replace(/\s/g, '');
    };
    _FontHelper.prototype._amendFallBackToUnicodeMap = function (properties) {
        if (!properties._fallBackToUnicodeMap) {
            return;
        }
        if (properties._fontStructure._toUnicode instanceof _PdfIdentityToUnicodeMap) {
            return;
        }
        var toUnicode = []; //eslint-disable-line
        for (var charCode in properties._fallBackToUnicodeMap) {
            if (properties._fontStructure._toUnicode._has(charCode)) {
                continue;
            }
            toUnicode[Number.parseInt(charCode.toString(), 10)] = properties._fallBackToUnicodeMap[Number.parseInt(charCode.toString(), 10)];
        }
        if (toUnicode.length > 0) {
            properties._fontStructure._toUnicode._amend(toUnicode);
        }
    };
    _FontHelper.prototype._applyStandardFontGlyphMap = function (map, glyphMap) {
        var keys = Object.keys(glyphMap); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var charCode = keys[Number.parseInt(i.toString(), 10)]; //eslint-disable-line
            map[+charCode] = glyphMap[Number.parseInt(charCode.toString(), 10)];
        }
    };
    _FontHelper.prototype._setFallBackSystemFont = function (properties) {
        var _this = this;
        this._fontStructure._missingFile = true;
        var name = this._fontStructure._name;
        var type = this._fontStructure._type;
        var fontName = this._normalizeFontName(name);
        var stdFontMap = _getStdFontMap(); //eslint-disable-line
        var nonStdFontMap = _getNonStdFontMap(); //eslint-disable-line
        var isStandardFont = !!stdFontMap[fontName]; //eslint-disable-line
        var isMappedToStandardFont = !!(nonStdFontMap[fontName] && stdFontMap //eslint-disable-line
        [nonStdFontMap[fontName]]); //eslint-disable-line
        fontName = stdFontMap[fontName] || nonStdFontMap[fontName] //eslint-disable-line
            || fontName;
        var fontBasicMetricsMap = _getFontBasicMetrics(); //eslint-disable-line
        var metrics = fontBasicMetricsMap[fontName]; //eslint-disable-line
        if (metrics) {
            if (isNaN(this._fontStructure._ascent)) {
                this._fontStructure._ascent = metrics.ascent / 1000;
            }
            if (isNaN(this._fontStructure._descent)) {
                this._fontStructure._descent = metrics.descent / 1000;
            }
            if (isNaN(this._fontStructure._capHeight)) {
                this._fontStructure._capHeight = metrics.capHeight / 1000;
            }
        }
        this._fontStructure._bold = /bold/gi.test(fontName);
        this._fontStructure._italic = /oblique|italic/gi.test(fontName);
        this._fontStructure._black = /Black/g.test(name);
        var isNarrow = /Narrow/g.test(name);
        this._remeasure = (!isStandardFont || isNarrow) && Object.keys(this._fontStructure._widths).length > 0;
        if ((isStandardFont || isMappedToStandardFont) && type === 'CIDFontType2' && this._fontStructure._encoding.startsWith('Identity-')) {
            var cidToGidMap_1 = properties.cidToGidMap; //eslint-disable-line
            var map_2 = []; //eslint-disable-line
            this._applyStandardFontGlyphMap(map_2, _getGlyphMapForStandardFonts());
            if (/Arial-?Black/i.test(name)) {
                this._applyStandardFontGlyphMap(map_2, _getSupplementalGlyphMapForArialBlack());
            }
            else if (/Calibri/i.test(name)) {
                this._applyStandardFontGlyphMap(map_2, _getFontGlyphMap());
            }
            if (cidToGidMap_1) {
                var keys = Object.keys(map_2); //eslint-disable-line
                for (var i = 0; i < keys.length; i++) {
                    var charCode = keys[Number.parseInt(i.toString(), 10)]; //eslint-disable-line
                    var cid = map_2[Number.parseInt(charCode.toString(), 10)]; //eslint-disable-line
                    if (cidToGidMap_1[Number.parseInt(cid.toString(), 10)] !== undefined) {
                        map_2[+charCode] = cidToGidMap_1[Number.parseInt(cid.toString(), 10)];
                    }
                }
                if (cidToGidMap_1.length !== this._fontStructure._toUnicode.length && properties.hasIncludedToUnicodeMap &&
                    this._fontStructure._toUnicode instanceof _PdfIdentityToUnicodeMap) {
                    this._fontStructure._toUnicode._forEach(function (charCode, unicodeCharCode) {
                        var cid = map_2[Number.parseInt(charCode.toString(), 10)]; //eslint-disable-line
                        if (cidToGidMap_1[Number.parseInt(cid.toString(), 10)] === undefined) {
                            map_2[+charCode] = unicodeCharCode;
                        }
                    });
                }
            }
            if (!(this._fontStructure._toUnicode instanceof _PdfIdentityToUnicodeMap)) {
                this._fontStructure._toUnicode._forEach(function (charCode, unicodeCharCode) {
                    map_2[+charCode] = unicodeCharCode;
                });
            }
            this._fontStructure._toFontChar = map_2;
            this._fontStructure._toUnicode = new _UnicodeMap(map_2);
        }
        else if (/Symbol/i.test(fontName)) {
            this._fontStructure._toFontChar = this._buildToFontChar(_symbolSetEncoding, _getGlyphsUnicode(), this._fontStructure._differences);
        }
        else if (/Dingbats/i.test(fontName)) {
            this._fontStructure._toFontChar = this._buildToFontChar(_zapfDingbatsEncoding, _getDingbatsGlyphsUnicode(), this._fontStructure._differences);
        }
        else if (isStandardFont) {
            var map_3 = this._buildToFontChar(this._fontStructure._defaultEncoding, _getGlyphsUnicode(), this._fontStructure._differences); //eslint-disable-line
            if (type === 'CIDFontType2' && !this._fontStructure._encoding.startsWith('Identity-') && !(this._fontStructure._toUnicode instanceof _PdfIdentityToUnicodeMap)) {
                this._fontStructure._toUnicode._forEach(function (charCode, unicodeCharCode) {
                    map_3[+charCode] = unicodeCharCode;
                });
            }
            this._fontStructure._toFontChar = map_3;
        }
        else {
            var glyphsUnicodeMap_1 = _getGlyphsUnicode(); //eslint-disable-line
            var map_4 = []; //eslint-disable-line
            this._fontStructure._toUnicode._forEach(function (charCode, unicodeCharCode) {
                if (!_this._fontStructure._composite) {
                    var glyphName = _this._fontStructure._differences[charCode] || _this._fontStructure._defaultEncoding[charCode]; //eslint-disable-line
                    var unicode = _getUnicodeForGlyph(glyphName, glyphsUnicodeMap_1); //eslint-disable-line
                    if (unicode !== -1) {
                        unicodeCharCode = unicode;
                    }
                }
                map_4[+charCode] = unicodeCharCode;
            });
            if (this._fontStructure._composite && this._fontStructure._toUnicode instanceof _PdfIdentityToUnicodeMap) {
                if (/Tahoma|Verdana/i.test(name)) {
                    this._applyStandardFontGlyphMap(map_4, _getGlyphMapForStandardFonts());
                }
            }
            this._fontStructure._toFontChar = map_4;
        }
        this._amendFallBackToUnicodeMap(properties);
    };
    Object.defineProperty(_FontHelper.prototype, "_spaceWidth", {
        get: function () {
            var possibleSpaceReplacements = ['space', 'minus', 'one', 'i', 'I'];
            var width;
            for (var i = 0; i < possibleSpaceReplacements.length; i++) {
                var glyphName = possibleSpaceReplacements[i]; //eslint-disable-line
                if (glyphName in this._fontStructure._widths) {
                    width = this._fontStructure._widths[glyphName]; //eslint-disable-line
                    break;
                }
                var glyphsUnicodeMap = _getGlyphsUnicode(); //eslint-disable-line
                var glyphUnicode = glyphsUnicodeMap[glyphName]; //eslint-disable-line  
                var charcode = 0;
                if (this._fontStructure._composite && this._fontStructure._characterMap._contains(glyphUnicode)) {
                    charcode = this._fontStructure._characterMap._lookup(glyphUnicode);
                    if (typeof charcode === 'string') {
                        charcode = this._convertCidString(glyphUnicode, charcode);
                    }
                }
                if (!charcode && this._fontStructure._toUnicode) {
                    charcode = this._fontStructure._toUnicode._charCodeOf(glyphUnicode);
                }
                if (charcode <= 0) {
                    charcode = glyphUnicode;
                }
                width = this._fontStructure._widths[charcode]; //eslint-disable-line
                if (width) {
                    break;
                }
            }
            return width;
        },
        enumerable: true,
        configurable: true
    });
    _FontHelper.prototype._charToGlyph = function (charCode, isSpace) {
        if (isSpace === void 0) { isSpace = false; }
        var vmetrics; //eslint-disable-line
        var glyph; //eslint-disable-line
        if (this._fontStructure._glyphCache) {
            glyph = this._fontStructure._glyphCache[Number.parseInt(charCode.toString(), 10)];
        }
        if (typeof (glyph) !== 'undefined' && glyph !== null && glyph.isSpace === isSpace) {
            return glyph;
        }
        var fontCharCode; //eslint-disable-line
        var width;
        var widthCode = charCode; //eslint-disable-line
        var cMap = this._fontStructure._characterMap; //eslint-disable-line
        if (cMap && cMap._contains(charCode)) {
            widthCode = this._fontStructure._characterMap._lookup(charCode);
            if (typeof widthCode === 'string') {
                widthCode = this._convertCidString(charCode, widthCode);
            }
        }
        width = this._fontStructure._widths[Number.parseInt(widthCode.toString(), 10)];
        if (typeof width !== 'number') {
            width = this._fontStructure._defaultWidth;
        }
        var vmetric; //eslint-disable-line
        if (vmetrics) {
            vmetric = vmetrics[Number.parseInt(widthCode.toString(), 10)];
        }
        var unicode = this._fontStructure._toUnicode._get(charCode) || charCode; //eslint-disable-line
        if (typeof unicode === 'number') {
            unicode = String.fromCharCode(unicode);
        }
        var isInFont = false;
        if (this._fontStructure._missingFile) {
            var glyphName = this._fontStructure._differences[Number.parseInt(charCode.toString(), 10)] || this._fontStructure._defaultEncoding[Number.parseInt(charCode.toString(), 10)]; //eslint-disable-line
            if ((glyphName === '.notdef' || glyphName === '') && this._fontStructure._type === 'Type1') {
                fontCharCode = 0x20;
                if (glyphName === '') {
                    if (!width) {
                        width = this._spaceWidth;
                    }
                    unicode = String.fromCharCode(fontCharCode);
                }
            }
        }
        var accent; //eslint-disable-line
        if (this._standardCharacter && this._standardCharacter[Number.parseInt(charCode.toString(), 10)]) {
            isInFont = true;
            var accentedCharcter = this._standardCharacter[Number.parseInt(charCode.toString(), 10)]; //eslint-disable-line
            accent = { fontChar: String.fromCodePoint(accentedCharcter.accentFontCharCode), offset: accentedCharcter.accentOffset };
        }
        glyph = new _Glyph(unicode, accent, width, vmetric, isSpace, isInFont);
        return (this._fontStructure._glyphCache[Number.parseInt(charCode.toString(), 10)] = glyph);
    };
    _FontHelper.prototype._convertCidString = function (characterCode, characterIdentifier, shouldThrow) {
        if (shouldThrow === void 0) { shouldThrow = false; }
        switch (characterIdentifier.length) {
            case 1:
                return characterIdentifier.charCodeAt(0);
            case 2:
                return (characterIdentifier.charCodeAt(0) << 8) | characterIdentifier.charCodeAt(1);
        }
        var msg = "Unsupported CID string (charCode " + characterCode + "): '" + characterIdentifier + "'.";
        if (shouldThrow) {
            throw new FormatError(msg);
        }
        return characterIdentifier;
    };
    _FontHelper.prototype._isTrueTypeCollectionFile = function (file) {
        var header = file.peekBytes(4); //eslint-disable-line
        return _bytesToString(header) === 'ttcf';
    };
    _FontHelper.prototype._readTrueTypeCollectionHeader = function (data) {
        var ttcTag = data.getString(4); //eslint-disable-line
        var majorVersion = data.getUnsignedInteger16();
        var minorVersion = data.getUnsignedInteger16();
        var numFonts = data.getInt32() >>> 0;
        var offsetTable = []; //eslint-disable-line
        for (var i = 0; i < numFonts; i++) {
            offsetTable.push(data.getInt32() >>> 0);
        }
        var header = { ttcTag: ttcTag, majorVersion: majorVersion, minorVersion: minorVersion, numFonts: numFonts, offsetTable: offsetTable }; //eslint-disable-line
        switch (majorVersion) {
            case 1:
                return header;
            case 2:
                // header.dsigTag = ttc.getInt32() >>> 0;
                // header.dsigLength = ttc.getInt32() >>> 0;
                // header.dsigOffset = ttc.getInt32() >>> 0;
                return header;
        }
        throw new FormatError("Invalid TrueType Collection majorVersion: " + majorVersion + ".");
    };
    _FontHelper.prototype._getString = function (length, file) {
        return _bytesToString(file.getBytes(length));
    };
    _FontHelper.prototype._readOpenTypeHeader = function (ttf) {
        return { version: this._getString(4, ttf), numTables: ttf.getUnsignedInteger16(), searchRange: ttf.getUnsignedInteger16(),
            entrySelector: ttf.getUnsignedInteger16(), rangeShift: ttf.getUnsignedInteger16() };
    };
    _FontHelper.prototype._readTables = function (file, numberOfTables) {
        var tables = Object.create(null); //eslint-disable-line
        tables['OS/2'] = null;
        tables.cmap = null;
        tables.head = null;
        tables.hhea = null;
        tables.hmtx = null;
        tables.maxp = null;
        tables.name = null;
        tables.post = null;
        for (var i = 0; i < numberOfTables; i++) {
            var table = this._readTableEntry(file); //eslint-disable-line
            if (!this._validTables.includes(table.tag)) {
                continue;
            }
            if (table.length === 0) {
                continue;
            }
            tables[table.tag] = table;
        }
        return tables;
    };
    _FontHelper.prototype._readTableEntry = function (file) {
        var tag = this._getString(4, file);
        var checksum = file.getInt32() >>> 0;
        var offset = file.getInt32() >>> 0;
        var length = file.getInt32() >>> 0;
        var previousPosition = file.position;
        file.pos = file.start || 0;
        file.position = file.pos;
        file.skip(offset);
        var data = file.getBytes(length); //eslint-disable-line
        file.pos = previousPosition;
        file.position = file.pos;
        if (tag === 'head') {
            data[8] = data[9] = data[10] = data[11] = 0;
            data[17] |= 0x20;
        }
        return { tag: tag, checksum: checksum, length: length, offset: offset, data: data };
    };
    _FontHelper.prototype._isMacNameRecord = function (r) {
        return r.platform === 1 && r.encoding === 0 && r.language === 0;
    };
    _FontHelper.prototype._isWinNameRecord = function (r) {
        return r.platform === 3 && r.encoding === 1 && r.language === 0x409;
    };
    _FontHelper.prototype._readNameTable = function (nameTable, font) {
        var start = (font.start || 0) + nameTable.offset;
        font.pos = start;
        var names = [[], []], records = []; //eslint-disable-line
        var length = nameTable.length;
        var end = start + length;
        var format = font.getUnsignedInteger16();
        var FORMAT_0_HEADER_LENGTH = 6;
        if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) {
            return [names, records];
        }
        var numRecords = font.getUnsignedInteger16();
        var stringsStart = font.getUnsignedInteger16();
        var NAME_RECORD_LENGTH = 12;
        var i;
        var ii;
        for (i = 0; i < numRecords && font.pos + NAME_RECORD_LENGTH <= end; i++) {
            var r = { platform: font.getUnsignedInteger16(), encoding: font.getUnsignedInteger16(), language: font.getUnsignedInteger16(), name: font.getUnsignedInteger16(),
                length: font.getUnsignedInteger16(), offset: font.getUnsignedInteger16() };
            if (this._isMacNameRecord(r) || this._isWinNameRecord(r)) {
                records.push(r);
            }
        }
        for (i = 0, ii = records.length; i < ii; i++) {
            var record = records[Number.parseInt(i.toString(), 10)]; //eslint-disable-line
            if (record.length <= 0) {
                continue;
            }
            var pos = start + stringsStart + record.offset;
            if (pos + record.length > end) {
                continue;
            }
            font.pos = pos;
            var nameIndex = record.name; //eslint-disable-line
            if (record.encoding) {
                var str = '';
                for (var j = 0, jj = record.length; j < jj; j += 2) {
                    str += String.fromCharCode(font.getUnsignedInteger16());
                }
                names[1][Number.parseInt(nameIndex.toString(), 10)] = str;
            }
            else {
                names[0][Number.parseInt(nameIndex.toString(), 10)] = font.getString(record.length);
            }
        }
        return [names, records];
    };
    _FontHelper.prototype._readTrueTypeCollectionData = function (data, fontName, font) {
        var _a = this._readTrueTypeCollectionHeader(data), numFonts = _a.numFonts, offsetTable = _a.offsetTable; //eslint-disable-line
        var fontNameParts = fontName.split('+'); //eslint-disable-line
        var fallbackData; //eslint-disable-line
        for (var i = 0; i < numFonts; i++) {
            data.pos = (data.start || 0) + offsetTable[Number.parseInt(i.toString(), 10)];
            var potentialHeader = this._readOpenTypeHeader(data); //eslint-disable-line
            var potentialTables = this._readTables(data, potentialHeader.numTables); //eslint-disable-line   
            if (!potentialTables.name) {
                throw new FormatError('TrueType Collection font must contain a name table.');
            }
            var nameTable = this._readNameTable(potentialTables.name, font)[0];
            for (var j = 0, jj = nameTable.length; j < jj; j++) {
                for (var k = 0, kk = nameTable[Number.parseInt(j.toString(), 10)].length; k < kk; k++) {
                    var nameEntry = nameTable[Number.parseInt(j.toString(), 10)][Number.parseInt(k.toString(), 10)] && nameTable[Number.parseInt(j.toString(), 10)][Number.parseInt(k.toString(), 10)].replaceAll(/\s/g, ''); //eslint-disable-line  
                    if (!nameEntry) {
                        continue;
                    }
                    if (nameEntry === fontName) {
                        return { header: potentialHeader, tables: potentialTables };
                    }
                    if (fontNameParts.length < 2) {
                        continue;
                    }
                    for (var _i = 0, fontNameParts_1 = fontNameParts; _i < fontNameParts_1.length; _i++) {
                        var part = fontNameParts_1[_i];
                        if (nameEntry === part) {
                            fallbackData = { name: part, header: potentialHeader, tables: potentialTables };
                        }
                    }
                }
            }
        }
        if (fallbackData) {
            return { header: fallbackData.header, tables: fallbackData.tables };
        }
        throw new FormatError("TrueType Collection does not contain '" + fontName + "' font.");
    };
    _FontHelper.prototype._int16 = function (b0, b1) {
        return (b0 << 8) + b1;
    };
    _FontHelper.prototype._checkAndRepair = function (font) {
        font = new _PdfStream(new Uint8Array(font.getBytes()));
        var header; //eslint-disable-line
        var tables; //eslint-disable-line
        if (this._isTrueTypeCollectionFile(font)) {
            var ttcData = this._readTrueTypeCollectionData(font, this._fontStructure._name, font); //eslint-disable-line
            header = ttcData.header;
            tables = ttcData.tables;
        }
        else {
            header = this._readOpenTypeHeader(font);
            tables = this._readTables(font, header.numTables);
        }
        var isTrueType = !tables['compactFont '];
        if (!isTrueType) {
            var isComposite = this._fontStructure._composite && (this._characterIdToGlyphMap &&
                this._characterIdToGlyphMap.length > 0 || !(this._fontStructure._characterMap instanceof _PdfIdentityCharacterMap));
            if ((header.version === 'OTTO' && !isComposite) || !tables.head || !tables.hhea || !tables.maxp || !tables.post) {
                this._adjustWidths();
            }
            delete tables.glyf;
            delete tables.loca;
            delete tables.fpgm;
            delete tables.prep;
            delete tables['cvt '];
            this._isOpenType = true;
        }
        else {
            if (!tables.loca) {
                throw new FormatError('Required loca table is not found');
            }
            if (!tables.glyf) {
                tables.glyf = { tag: 'glyf', data: new Uint8Array(0) };
            }
            this._isOpenType = false;
        }
        if (!tables.maxp) {
            throw new FormatError('Required maxp table is not found');
        }
        font.pos = (font.start || 0) + tables.maxp.offset;
        font.position = font.pos;
        var version = font.getInt32();
        font.pos = font.position;
        var numGlyphs = font.getUnsignedInteger16();
        font.pos = font.position;
        if (version !== 0x00010000 && version !== 0x00005000) {
            if (tables.maxp.length === 6) {
                version = 0x0005000;
            }
            else if (tables.maxp.length >= 32) {
                version = 0x00010000;
            }
            else {
                throw new FormatError('maxp table has a wrong version number');
            }
            this._writeUnSignedInt32(tables.maxp.data, 0, version);
        }
        if (this._scaleFactors && this._scaleFactors.length === numGlyphs && isTrueType) {
            var _scaleFactors = this._scaleFactors;
            var isGlyphLocationsLong = this._int16(tables.head.data[50], tables.head.data[51]);
            var glyphs = new _PdfGlyphTable({ glyfTable: tables.glyf.data, isGlyphLocationsLong: isGlyphLocationsLong, locaTable: tables.loca.data, numGlyphs: numGlyphs });
            glyphs.scale(_scaleFactors);
            var _a = glyphs._write(), data = _a.data, loca = _a.loca, isLocationLong = _a.isLocationLong;
            tables.glyf.data = data;
            tables.loca.data = loca;
            if (isLocationLong !== !!isGlyphLocationsLong) {
                tables.head.data[50] = 0;
                tables.head.data[51] = isLocationLong ? 1 : 0;
            }
        }
        if (!tables.hhea) {
            throw new FormatError('Required hhea table is not found');
        }
        if (tables.hhea.data[10] === 0 && tables.hhea.data[11] === 0) {
            tables.hhea.data[10] = 0xff;
            tables.hhea.data[11] = 0xff;
        }
        var metricsOverride = { unitsPerEm: this._int16(tables.head.data[18], tables.head.data[19]),
            yMax: this._signedInt16(tables.head.data[42], tables.head.data[43]),
            yMin: this._signedInt16(tables.head.data[38], tables.head.data[39]),
            ascent: this._signedInt16(tables.hhea.data[4], tables.hhea.data[5]),
            descent: this._signedInt16(tables.hhea.data[6], tables.hhea.data[7]),
            lineGap: this._signedInt16(tables.hhea.data[8], tables.hhea.data[9])
        };
        this._fontStructure._ascent = metricsOverride.ascent / metricsOverride.unitsPerEm;
        this._fontStructure._descent = metricsOverride.descent / metricsOverride.unitsPerEm;
        this._fontStructure._lineGap = metricsOverride.lineGap / metricsOverride.unitsPerEm;
        if (this._fontStructure._cssFontInfo && this._fontStructure._cssFontInfo.lineHeight) {
            this._fontStructure._lineHeight = this._fontStructure._cssFontInfo.metrics.lineHeight;
            this._fontStructure._lineGap = this._fontStructure._cssFontInfo.metrics.lineGap;
        }
        else {
            this._fontStructure._lineHeight = this._fontStructure._ascent - this._fontStructure._descent + this._fontStructure._lineGap;
        }
        if (tables.name) {
            var _b = this._readNameTable(tables.name, font), namePrototype = _b[0], nameRecords = _b[1];
            this._fontStructure._psName = namePrototype[0][6] || null;
            if (!this._fontStructure._composite) {
                this._adjustTrueTypeToUnicode(this._fontStructure, this._fontStructure._isSymbolicFont, nameRecords);
            }
        }
    };
    _FontHelper.prototype._adjustType1ToUnicode = function () {
        if (this._fontStructure._isInternalFont) {
            return;
        }
        if (this._hasIncludedToUnicodeMap) {
            return;
        }
        if (this._fontStructure._builtInEncoding === this._fontStructure._defaultEncoding) {
            return;
        }
        if (this._fontStructure._toUnicode instanceof _PdfIdentityToUnicodeMap) {
            return;
        }
        var toUnicode = []; //eslint-disable-line
        var glyphsUnicodeMap = _getGlyphsUnicode(); //eslint-disable-line
        var keys = Object.keys(this._fontStructure._builtInEncoding); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var charCode = keys[Number.parseInt(i.toString(), 10)]; //eslint-disable-line
            if (this._hasEncoding) {
                if (this._baseEncodingName || this._fontStructure._differences[Number.parseInt(charCode.toString(), 10)] !== undefined) {
                    continue;
                }
            }
            var glyphName = this._fontStructure._builtInEncoding[Number.parseInt(charCode.toString(), 10)]; //eslint-disable-line
            var unicode = _getUnicodeForGlyph(glyphName, glyphsUnicodeMap); //eslint-disable-line
            if (unicode !== -1) {
                toUnicode[Number.parseInt(charCode.toString(), 10)] = String.fromCharCode(unicode);
            }
        }
        if (toUnicode.length > 0) {
            this._fontStructure._toUnicode._amend(toUnicode);
        }
    };
    _FontHelper.prototype._adjustTrueTypeToUnicode = function (properties, isSymbolicFont, nameRecords) {
        if (properties._isInternalFont) {
            return;
        }
        if (this._hasIncludedToUnicodeMap) {
            return;
        }
        if (this._hasEncoding) {
            return;
        }
        if (properties._toUnicode instanceof _PdfIdentityToUnicodeMap) {
            return;
        }
        if (!isSymbolicFont) {
            return;
        }
        if (nameRecords.length === 0) {
            return;
        }
        if (properties._defaultEncoding === _winAnsiEncoding) {
            return;
        }
        for (var _i = 0, nameRecords_1 = nameRecords; _i < nameRecords_1.length; _i++) {
            var r = nameRecords_1[_i];
            if (!this._isWinNameRecord(r)) {
                return;
            }
        }
        var encoding = _winAnsiEncoding;
        var toUnicode = []; //eslint-disable-line
        var glyphsUnicodeMap = _getGlyphsUnicode(); //eslint-disable-line
        var keys = Object.keys(encoding); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var charCode = keys[Number.parseInt(i.toString(), 10)]; //eslint-disable-line
            var glyphName = encoding[Number.parseInt(charCode.toString(), 10)]; //eslint-disable-line
            if (glyphName === '') {
                continue;
            }
            var unicode = glyphsUnicodeMap[Number.parseInt(glyphName.toString(), 10)]; //eslint-disable-line
            if (unicode === undefined) {
                continue;
            }
            toUnicode[Number.parseInt(charCode.toString(), 10)] = String.fromCharCode(unicode);
        }
        if (toUnicode.length > 0) {
            properties._toUnicode._amend(toUnicode);
        }
    };
    return _FontHelper;
}());
export { _FontHelper };
var _Glyph = /** @class */ (function () {
    function _Glyph(unicode, accent, width, _verticalMetrics, //eslint-disable-line
    isSpace, isInFont) {
        this._unicode = unicode;
        this._accent = accent;
        this._width = width;
        this._verticalMetrics = _verticalMetrics;
        this._isSpace = isSpace;
        this._isInFont = isInFont;
    }
    return _Glyph;
}());
export { _Glyph };
var _UnicodeMap = /** @class */ (function () {
    function _UnicodeMap(cmap) {
        this._map = cmap;
    }
    Object.defineProperty(_UnicodeMap.prototype, "_length", {
        get: function () {
            return this._map.length;
        },
        enumerable: true,
        configurable: true
    });
    _UnicodeMap.prototype._forEach = function () {
        var results = [];
        var keys = Object.keys(this._map); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var charCode = keys[Number.parseInt(i.toString(), 10)]; //eslint-disable-line
            var unicodeValue = this._map[Number.parseInt(charCode, 10)]; //eslint-disable-line
            if (unicodeValue) {
                results.push({
                    characterCode: Number.parseInt(charCode, 10),
                    unicode: unicodeValue.charCodeAt(0)
                });
            }
        }
        return results;
    };
    _UnicodeMap.prototype._has = function (i) {
        return typeof (this._map[Number.parseInt(i.toString(), 10)]) !== 'undefined';
    };
    _UnicodeMap.prototype._get = function (i) {
        return this._map[Number.parseInt(i.toString(), 10)];
    };
    _UnicodeMap.prototype._charCodeOf = function (value) {
        var map = this._map; //eslint-disable-line
        if (map.length <= 0x10000) {
            return map.indexOf(value);
        }
        var keys = Object.keys(map); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var charCode = keys[Number.parseInt(i.toString(), 10)]; //eslint-disable-line
            if (map[Number.parseInt(charCode.toString(), 10)] === value) {
                return Number.parseInt(charCode.toString(), 10);
            }
        }
        return -1;
    };
    _UnicodeMap.prototype._amend = function (map) {
        var keys = Object.keys(map); //eslint-disable-line
        for (var i = 0; i < keys.length; i++) {
            var charCode = keys[Number.parseInt(i.toString(), 10)]; //eslint-disable-line
            this._map[Number.parseInt(charCode.toString(), 10)] = map[Number.parseInt(charCode.toString(), 10)];
        }
    };
    return _UnicodeMap;
}());
var _PdfIdentityToUnicodeMap = /** @class */ (function () {
    function _PdfIdentityToUnicodeMap(firstChar, lastChar) {
        this._firstChar = firstChar;
        this._lastChar = lastChar;
    }
    Object.defineProperty(_PdfIdentityToUnicodeMap.prototype, "_length", {
        get: function () {
            return this._lastChar + 1 - this._firstChar;
        },
        enumerable: true,
        configurable: true
    });
    _PdfIdentityToUnicodeMap.prototype._forEach = function (callback) {
        for (var i = this._firstChar, ii = this._lastChar; i <= ii; i++) {
            callback(i, i);
        }
    };
    _PdfIdentityToUnicodeMap.prototype._has = function (index) {
        return this._firstChar <= index && index <= this._lastChar;
    };
    _PdfIdentityToUnicodeMap.prototype._get = function (index) {
        if (this._firstChar <= index && index <= this._lastChar) {
            return String.fromCharCode(index);
        }
        return undefined;
    };
    _PdfIdentityToUnicodeMap.prototype._charCodeOf = function (v) {
        return Number.isInteger(v) && v >= this._firstChar && v <= this._lastChar ? v : -1;
    };
    _PdfIdentityToUnicodeMap.prototype._amend = function () {
        throw new Error('Should not call amend()');
    };
    return _PdfIdentityToUnicodeMap;
}());
