How to use safeString16 method in wpt

Best JavaScript code snippet using wpt

fonts.js

Source:fonts.js Github

copy

Full Screen

...451 }452 function string16(value) {453 return String.fromCharCode(value >> 8 & 0xff, value & 0xff);454 }455 function safeString16(value) {456 value = value > 0x7FFF ? 0x7FFF : value < -0x8000 ? -0x8000 : value;457 return String.fromCharCode(value >> 8 & 0xff, value & 0xff);458 }459 function isTrueTypeFile(file) {460 var header = file.peekBytes(4);461 return (0, _util.readUint32)(header, 0) === 0x00010000;462 }463 function isOpenTypeFile(file) {464 var header = file.peekBytes(4);465 return (0, _util.bytesToString)(header) === 'OTTO';466 }467 function isType1File(file) {468 var header = file.peekBytes(2);469 if (header[0] === 0x25 && header[1] === 0x21) {470 return true;471 }472 if (header[0] === 0x80 && header[1] === 0x01) {473 return true;474 }475 return false;476 }477 function buildToFontChar(encoding, glyphsUnicodeMap, differences) {478 var toFontChar = [],479 unicode;480 for (var i = 0, ii = encoding.length; i < ii; i++) {481 unicode = (0, _unicode.getUnicodeForGlyph)(encoding[i], glyphsUnicodeMap);482 if (unicode !== -1) {483 toFontChar[i] = unicode;484 }485 }486 for (var charCode in differences) {487 unicode = (0, _unicode.getUnicodeForGlyph)(differences[charCode], glyphsUnicodeMap);488 if (unicode !== -1) {489 toFontChar[+charCode] = unicode;490 }491 }492 return toFontChar;493 }494 function isProblematicUnicodeLocation(code) {495 var i = 0,496 j = ProblematicCharRanges.length - 1;497 while (i < j) {498 var c = i + j + 1 >> 1;499 if (code < ProblematicCharRanges[c]) {500 j = c - 1;501 } else {502 i = c;503 }504 }505 return !(i & 1);506 }507 function adjustMapping(charCodeToGlyphId, properties, missingGlyphs) {508 var toUnicode = properties.toUnicode;509 var isSymbolic = !!(properties.flags & FontFlags.Symbolic);510 var isIdentityUnicode = properties.toUnicode instanceof IdentityToUnicodeMap;511 var newMap = Object.create(null);512 var toFontChar = [];513 var usedFontCharCodes = [];514 var nextAvailableFontCharCode = PRIVATE_USE_OFFSET_START;515 for (var originalCharCode in charCodeToGlyphId) {516 originalCharCode |= 0;517 var glyphId = charCodeToGlyphId[originalCharCode];518 if (missingGlyphs[glyphId]) {519 continue;520 }521 var fontCharCode = originalCharCode;522 var hasUnicodeValue = false;523 if (!isIdentityUnicode && toUnicode.has(originalCharCode)) {524 hasUnicodeValue = true;525 var unicode = toUnicode.get(fontCharCode);526 if (unicode.length === 1) {527 fontCharCode = unicode.charCodeAt(0);528 }529 }530 if (usedFontCharCodes[fontCharCode] !== undefined || isProblematicUnicodeLocation(fontCharCode) || isSymbolic && !hasUnicodeValue) {531 do {532 if (nextAvailableFontCharCode > PRIVATE_USE_OFFSET_END) {533 (0, _util.warn)('Ran out of space in font private use area.');534 break;535 }536 fontCharCode = nextAvailableFontCharCode++;537 if (SKIP_PRIVATE_USE_RANGE_F000_TO_F01F && fontCharCode === 0xF000) {538 fontCharCode = 0xF020;539 nextAvailableFontCharCode = fontCharCode + 1;540 }541 } while (usedFontCharCodes[fontCharCode] !== undefined);542 }543 newMap[fontCharCode] = glyphId;544 toFontChar[originalCharCode] = fontCharCode;545 usedFontCharCodes[fontCharCode] = true;546 }547 return {548 toFontChar: toFontChar,549 charCodeToGlyphId: newMap,550 nextAvailableFontCharCode: nextAvailableFontCharCode551 };552 }553 function getRanges(glyphs, numGlyphs) {554 var codes = [];555 for (var charCode in glyphs) {556 if (glyphs[charCode] >= numGlyphs) {557 continue;558 }559 codes.push({560 fontCharCode: charCode | 0,561 glyphId: glyphs[charCode]562 });563 }564 if (codes.length === 0) {565 codes.push({566 fontCharCode: 0,567 glyphId: 0568 });569 }570 codes.sort(function fontGetRangesSort(a, b) {571 return a.fontCharCode - b.fontCharCode;572 });573 var ranges = [];574 var length = codes.length;575 for (var n = 0; n < length;) {576 var start = codes[n].fontCharCode;577 var codeIndices = [codes[n].glyphId];578 ++n;579 var end = start;580 while (n < length && end + 1 === codes[n].fontCharCode) {581 codeIndices.push(codes[n].glyphId);582 ++end;583 ++n;584 if (end === 0xFFFF) {585 break;586 }587 }588 ranges.push([start, end, codeIndices]);589 }590 return ranges;591 }592 function createCmapTable(glyphs, numGlyphs) {593 var ranges = getRanges(glyphs, numGlyphs);594 var numTables = ranges[ranges.length - 1][1] > 0xFFFF ? 2 : 1;595 var cmap = '\x00\x00' + string16(numTables) + '\x00\x03' + '\x00\x01' + (0, _util.string32)(4 + numTables * 8);596 var i, ii, j, jj;597 for (i = ranges.length - 1; i >= 0; --i) {598 if (ranges[i][0] <= 0xFFFF) {599 break;600 }601 }602 var bmpLength = i + 1;603 if (ranges[i][0] < 0xFFFF && ranges[i][1] === 0xFFFF) {604 ranges[i][1] = 0xFFFE;605 }606 var trailingRangesCount = ranges[i][1] < 0xFFFF ? 1 : 0;607 var segCount = bmpLength + trailingRangesCount;608 var searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2);609 var startCount = '';610 var endCount = '';611 var idDeltas = '';612 var idRangeOffsets = '';613 var glyphsIds = '';614 var bias = 0;615 var range, start, end, codes;616 for (i = 0, ii = bmpLength; i < ii; i++) {617 range = ranges[i];618 start = range[0];619 end = range[1];620 startCount += string16(start);621 endCount += string16(end);622 codes = range[2];623 var contiguous = true;624 for (j = 1, jj = codes.length; j < jj; ++j) {625 if (codes[j] !== codes[j - 1] + 1) {626 contiguous = false;627 break;628 }629 }630 if (!contiguous) {631 var offset = (segCount - i) * 2 + bias * 2;632 bias += end - start + 1;633 idDeltas += string16(0);634 idRangeOffsets += string16(offset);635 for (j = 0, jj = codes.length; j < jj; ++j) {636 glyphsIds += string16(codes[j]);637 }638 } else {639 var startCode = codes[0];640 idDeltas += string16(startCode - start & 0xFFFF);641 idRangeOffsets += string16(0);642 }643 }644 if (trailingRangesCount > 0) {645 endCount += '\xFF\xFF';646 startCount += '\xFF\xFF';647 idDeltas += '\x00\x01';648 idRangeOffsets += '\x00\x00';649 }650 var format314 = '\x00\x00' + string16(2 * segCount) + string16(searchParams.range) + string16(searchParams.entry) + string16(searchParams.rangeShift) + endCount + '\x00\x00' + startCount + idDeltas + idRangeOffsets + glyphsIds;651 var format31012 = '';652 var header31012 = '';653 if (numTables > 1) {654 cmap += '\x00\x03' + '\x00\x0A' + (0, _util.string32)(4 + numTables * 8 + 4 + format314.length);655 format31012 = '';656 for (i = 0, ii = ranges.length; i < ii; i++) {657 range = ranges[i];658 start = range[0];659 codes = range[2];660 var code = codes[0];661 for (j = 1, jj = codes.length; j < jj; ++j) {662 if (codes[j] !== codes[j - 1] + 1) {663 end = range[0] + j - 1;664 format31012 += (0, _util.string32)(start) + (0, _util.string32)(end) + (0, _util.string32)(code);665 start = end + 1;666 code = codes[j];667 }668 }669 format31012 += (0, _util.string32)(start) + (0, _util.string32)(range[1]) + (0, _util.string32)(code);670 }671 header31012 = '\x00\x0C' + '\x00\x00' + (0, _util.string32)(format31012.length + 16) + '\x00\x00\x00\x00' + (0, _util.string32)(format31012.length / 12);672 }673 return cmap + '\x00\x04' + string16(format314.length + 4) + format314 + header31012 + format31012;674 }675 function validateOS2Table(os2) {676 var stream = new _stream.Stream(os2.data);677 var version = stream.getUint16();678 stream.getBytes(60);679 var selection = stream.getUint16();680 if (version < 4 && selection & 0x0300) {681 return false;682 }683 var firstChar = stream.getUint16();684 var lastChar = stream.getUint16();685 if (firstChar > lastChar) {686 return false;687 }688 stream.getBytes(6);689 var usWinAscent = stream.getUint16();690 if (usWinAscent === 0) {691 return false;692 }693 os2.data[8] = os2.data[9] = 0;694 return true;695 }696 function createOS2Table(properties, charstrings, override) {697 override = override || {698 unitsPerEm: 0,699 yMax: 0,700 yMin: 0,701 ascent: 0,702 descent: 0703 };704 var ulUnicodeRange1 = 0;705 var ulUnicodeRange2 = 0;706 var ulUnicodeRange3 = 0;707 var ulUnicodeRange4 = 0;708 var firstCharIndex = null;709 var lastCharIndex = 0;710 if (charstrings) {711 for (var code in charstrings) {712 code |= 0;713 if (firstCharIndex > code || !firstCharIndex) {714 firstCharIndex = code;715 }716 if (lastCharIndex < code) {717 lastCharIndex = code;718 }719 var position = (0, _unicode.getUnicodeRangeFor)(code);720 if (position < 32) {721 ulUnicodeRange1 |= 1 << position;722 } else if (position < 64) {723 ulUnicodeRange2 |= 1 << position - 32;724 } else if (position < 96) {725 ulUnicodeRange3 |= 1 << position - 64;726 } else if (position < 123) {727 ulUnicodeRange4 |= 1 << position - 96;728 } else {729 throw new _util.FormatError('Unicode ranges Bits > 123 are reserved for internal usage');730 }731 }732 } else {733 firstCharIndex = 0;734 lastCharIndex = 255;735 }736 var bbox = properties.bbox || [0, 0, 0, 0];737 var unitsPerEm = override.unitsPerEm || 1 / (properties.fontMatrix || _util.FONT_IDENTITY_MATRIX)[0];738 var scale = properties.ascentScaled ? 1.0 : unitsPerEm / PDF_GLYPH_SPACE_UNITS;739 var typoAscent = override.ascent || Math.round(scale * (properties.ascent || bbox[3]));740 var typoDescent = override.descent || Math.round(scale * (properties.descent || bbox[1]));741 if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) {742 typoDescent = -typoDescent;743 }744 var winAscent = override.yMax || typoAscent;745 var winDescent = -override.yMin || -typoDescent;746 return '\x00\x03' + '\x02\x24' + '\x01\xF4' + '\x00\x05' + '\x00\x00' + '\x02\x8A' + '\x02\xBB' + '\x00\x00' + '\x00\x8C' + '\x02\x8A' + '\x02\xBB' + '\x00\x00' + '\x01\xDF' + '\x00\x31' + '\x01\x02' + '\x00\x00' + '\x00\x00\x06' + String.fromCharCode(properties.fixedPitch ? 0x09 : 0x00) + '\x00\x00\x00\x00\x00\x00' + (0, _util.string32)(ulUnicodeRange1) + (0, _util.string32)(ulUnicodeRange2) + (0, _util.string32)(ulUnicodeRange3) + (0, _util.string32)(ulUnicodeRange4) + '\x2A\x32\x31\x2A' + string16(properties.italicAngle ? 1 : 0) + string16(firstCharIndex || properties.firstChar) + string16(lastCharIndex || properties.lastChar) + string16(typoAscent) + string16(typoDescent) + '\x00\x64' + string16(winAscent) + string16(winDescent) + '\x00\x00\x00\x00' + '\x00\x00\x00\x00' + string16(properties.xHeight) + string16(properties.capHeight) + string16(0) + string16(firstCharIndex || properties.firstChar) + '\x00\x03';747 }748 function createPostTable(properties) {749 var angle = Math.floor(properties.italicAngle * Math.pow(2, 16));750 return '\x00\x03\x00\x00' + (0, _util.string32)(angle) + '\x00\x00' + '\x00\x00' + (0, _util.string32)(properties.fixedPitch) + '\x00\x00\x00\x00' + '\x00\x00\x00\x00' + '\x00\x00\x00\x00' + '\x00\x00\x00\x00';751 }752 function createNameTable(name, proto) {753 if (!proto) {754 proto = [[], []];755 }756 var strings = [proto[0][0] || 'Original licence', proto[0][1] || name, proto[0][2] || 'Unknown', proto[0][3] || 'uniqueID', proto[0][4] || name, proto[0][5] || 'Version 0.11', proto[0][6] || '', proto[0][7] || 'Unknown', proto[0][8] || 'Unknown', proto[0][9] || 'Unknown'];757 var stringsUnicode = [];758 var i, ii, j, jj, str;759 for (i = 0, ii = strings.length; i < ii; i++) {760 str = proto[1][i] || strings[i];761 var strBufUnicode = [];762 for (j = 0, jj = str.length; j < jj; j++) {763 strBufUnicode.push(string16(str.charCodeAt(j)));764 }765 stringsUnicode.push(strBufUnicode.join(''));766 }767 var names = [strings, stringsUnicode];768 var platforms = ['\x00\x01', '\x00\x03'];769 var encodings = ['\x00\x00', '\x00\x01'];770 var languages = ['\x00\x00', '\x04\x09'];771 var namesRecordCount = strings.length * platforms.length;772 var nameTable = '\x00\x00' + string16(namesRecordCount) + string16(namesRecordCount * 12 + 6);773 var strOffset = 0;774 for (i = 0, ii = platforms.length; i < ii; i++) {775 var strs = names[i];776 for (j = 0, jj = strs.length; j < jj; j++) {777 str = strs[j];778 var nameRecord = platforms[i] + encodings[i] + languages[i] + string16(j) + string16(str.length) + string16(strOffset);779 nameTable += nameRecord;780 strOffset += str.length;781 }782 }783 nameTable += strings.join('') + stringsUnicode.join('');784 return nameTable;785 }786 Font.prototype = {787 name: null,788 font: null,789 mimetype: null,790 encoding: null,791 get renderer() {792 var renderer = _font_renderer.FontRendererFactory.create(this, SEAC_ANALYSIS_ENABLED);793 return (0, _util.shadow)(this, 'renderer', renderer);794 },795 exportData: function Font_exportData() {796 var data = {};797 for (var i in this) {798 if (this.hasOwnProperty(i)) {799 data[i] = this[i];800 }801 }802 return data;803 },804 fallbackToSystemFont: function Font_fallbackToSystemFont() {805 var _this = this;806 this.missingFile = true;807 var charCode, unicode;808 var name = this.name;809 var type = this.type;810 var subtype = this.subtype;811 var fontName = name.replace(/[,_]/g, '-');812 var stdFontMap = (0, _standard_fonts.getStdFontMap)(),813 nonStdFontMap = (0, _standard_fonts.getNonStdFontMap)();814 var isStandardFont = !!stdFontMap[fontName] || !!(nonStdFontMap[fontName] && stdFontMap[nonStdFontMap[fontName]]);815 fontName = stdFontMap[fontName] || nonStdFontMap[fontName] || fontName;816 this.bold = fontName.search(/bold/gi) !== -1;817 this.italic = fontName.search(/oblique/gi) !== -1 || fontName.search(/italic/gi) !== -1;818 this.black = name.search(/Black/g) !== -1;819 this.remeasure = Object.keys(this.widths).length > 0;820 if (isStandardFont && type === 'CIDFontType2' && this.cidEncoding.indexOf('Identity-') === 0) {821 var GlyphMapForStandardFonts = (0, _standard_fonts.getGlyphMapForStandardFonts)();822 var map = [];823 for (charCode in GlyphMapForStandardFonts) {824 map[+charCode] = GlyphMapForStandardFonts[charCode];825 }826 if (/Arial-?Black/i.test(name)) {827 var SupplementalGlyphMapForArialBlack = (0, _standard_fonts.getSupplementalGlyphMapForArialBlack)();828 for (charCode in SupplementalGlyphMapForArialBlack) {829 map[+charCode] = SupplementalGlyphMapForArialBlack[charCode];830 }831 }832 var isIdentityUnicode = this.toUnicode instanceof IdentityToUnicodeMap;833 if (!isIdentityUnicode) {834 this.toUnicode.forEach(function (charCode, unicodeCharCode) {835 map[+charCode] = unicodeCharCode;836 });837 }838 this.toFontChar = map;839 this.toUnicode = new ToUnicodeMap(map);840 } else if (/Symbol/i.test(fontName)) {841 this.toFontChar = buildToFontChar(_encodings.SymbolSetEncoding, (0, _glyphlist.getGlyphsUnicode)(), this.differences);842 } else if (/Dingbats/i.test(fontName)) {843 if (/Wingdings/i.test(name)) {844 (0, _util.warn)('Non-embedded Wingdings font, falling back to ZapfDingbats.');845 }846 this.toFontChar = buildToFontChar(_encodings.ZapfDingbatsEncoding, (0, _glyphlist.getDingbatsGlyphsUnicode)(), this.differences);847 } else if (isStandardFont) {848 this.toFontChar = buildToFontChar(this.defaultEncoding, (0, _glyphlist.getGlyphsUnicode)(), this.differences);849 } else {850 var glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)();851 this.toUnicode.forEach(function (charCode, unicodeCharCode) {852 if (!_this.composite) {853 var glyphName = _this.differences[charCode] || _this.defaultEncoding[charCode];854 unicode = (0, _unicode.getUnicodeForGlyph)(glyphName, glyphsUnicodeMap);855 if (unicode !== -1) {856 unicodeCharCode = unicode;857 }858 }859 _this.toFontChar[charCode] = unicodeCharCode;860 });861 }862 this.loadedName = fontName.split('-')[0];863 this.loading = false;864 this.fontType = getFontType(type, subtype);865 },866 checkAndRepair: function Font_checkAndRepair(name, font, properties) {867 function readTableEntry(file) {868 var tag = (0, _util.bytesToString)(file.getBytes(4));869 var checksum = file.getInt32() >>> 0;870 var offset = file.getInt32() >>> 0;871 var length = file.getInt32() >>> 0;872 var previousPosition = file.pos;873 file.pos = file.start ? file.start : 0;874 file.skip(offset);875 var data = file.getBytes(length);876 file.pos = previousPosition;877 if (tag === 'head') {878 data[8] = data[9] = data[10] = data[11] = 0;879 data[17] |= 0x20;880 }881 return {882 tag: tag,883 checksum: checksum,884 length: length,885 offset: offset,886 data: data887 };888 }889 function readOpenTypeHeader(ttf) {890 return {891 version: (0, _util.bytesToString)(ttf.getBytes(4)),892 numTables: ttf.getUint16(),893 searchRange: ttf.getUint16(),894 entrySelector: ttf.getUint16(),895 rangeShift: ttf.getUint16()896 };897 }898 function readCmapTable(cmap, font, isSymbolicFont, hasEncoding) {899 if (!cmap) {900 (0, _util.warn)('No cmap table available.');901 return {902 platformId: -1,903 encodingId: -1,904 mappings: [],905 hasShortCmap: false906 };907 }908 var segment;909 var start = (font.start ? font.start : 0) + cmap.offset;910 font.pos = start;911 font.getUint16();912 var numTables = font.getUint16();913 var potentialTable;914 var canBreak = false;915 for (var i = 0; i < numTables; i++) {916 var platformId = font.getUint16();917 var encodingId = font.getUint16();918 var offset = font.getInt32() >>> 0;919 var useTable = false;920 if (potentialTable && potentialTable.platformId === platformId && potentialTable.encodingId === encodingId) {921 continue;922 }923 if (platformId === 0 && encodingId === 0) {924 useTable = true;925 } else if (platformId === 1 && encodingId === 0) {926 useTable = true;927 } else if (platformId === 3 && encodingId === 1 && (hasEncoding || !potentialTable)) {928 useTable = true;929 if (!isSymbolicFont) {930 canBreak = true;931 }932 } else if (isSymbolicFont && platformId === 3 && encodingId === 0) {933 useTable = true;934 canBreak = true;935 }936 if (useTable) {937 potentialTable = {938 platformId: platformId,939 encodingId: encodingId,940 offset: offset941 };942 }943 if (canBreak) {944 break;945 }946 }947 if (potentialTable) {948 font.pos = start + potentialTable.offset;949 }950 if (!potentialTable || font.peekByte() === -1) {951 (0, _util.warn)('Could not find a preferred cmap table.');952 return {953 platformId: -1,954 encodingId: -1,955 mappings: [],956 hasShortCmap: false957 };958 }959 var format = font.getUint16();960 font.getUint16();961 font.getUint16();962 var hasShortCmap = false;963 var mappings = [];964 var j, glyphId;965 if (format === 0) {966 for (j = 0; j < 256; j++) {967 var index = font.getByte();968 if (!index) {969 continue;970 }971 mappings.push({972 charCode: j,973 glyphId: index974 });975 }976 hasShortCmap = true;977 } else if (format === 4) {978 var segCount = font.getUint16() >> 1;979 font.getBytes(6);980 var segIndex,981 segments = [];982 for (segIndex = 0; segIndex < segCount; segIndex++) {983 segments.push({ end: font.getUint16() });984 }985 font.getUint16();986 for (segIndex = 0; segIndex < segCount; segIndex++) {987 segments[segIndex].start = font.getUint16();988 }989 for (segIndex = 0; segIndex < segCount; segIndex++) {990 segments[segIndex].delta = font.getUint16();991 }992 var offsetsCount = 0;993 for (segIndex = 0; segIndex < segCount; segIndex++) {994 segment = segments[segIndex];995 var rangeOffset = font.getUint16();996 if (!rangeOffset) {997 segment.offsetIndex = -1;998 continue;999 }1000 var offsetIndex = (rangeOffset >> 1) - (segCount - segIndex);1001 segment.offsetIndex = offsetIndex;1002 offsetsCount = Math.max(offsetsCount, offsetIndex + segment.end - segment.start + 1);1003 }1004 var offsets = [];1005 for (j = 0; j < offsetsCount; j++) {1006 offsets.push(font.getUint16());1007 }1008 for (segIndex = 0; segIndex < segCount; segIndex++) {1009 segment = segments[segIndex];1010 start = segment.start;1011 var end = segment.end;1012 var delta = segment.delta;1013 offsetIndex = segment.offsetIndex;1014 for (j = start; j <= end; j++) {1015 if (j === 0xFFFF) {1016 continue;1017 }1018 glyphId = offsetIndex < 0 ? j : offsets[offsetIndex + j - start];1019 glyphId = glyphId + delta & 0xFFFF;1020 mappings.push({1021 charCode: j,1022 glyphId: glyphId1023 });1024 }1025 }1026 } else if (format === 6) {1027 var firstCode = font.getUint16();1028 var entryCount = font.getUint16();1029 for (j = 0; j < entryCount; j++) {1030 glyphId = font.getUint16();1031 var charCode = firstCode + j;1032 mappings.push({1033 charCode: charCode,1034 glyphId: glyphId1035 });1036 }1037 } else {1038 (0, _util.warn)('cmap table has unsupported format: ' + format);1039 return {1040 platformId: -1,1041 encodingId: -1,1042 mappings: [],1043 hasShortCmap: false1044 };1045 }1046 mappings.sort(function (a, b) {1047 return a.charCode - b.charCode;1048 });1049 for (i = 1; i < mappings.length; i++) {1050 if (mappings[i - 1].charCode === mappings[i].charCode) {1051 mappings.splice(i, 1);1052 i--;1053 }1054 }1055 return {1056 platformId: potentialTable.platformId,1057 encodingId: potentialTable.encodingId,1058 mappings: mappings,1059 hasShortCmap: hasShortCmap1060 };1061 }1062 function sanitizeMetrics(font, header, metrics, numGlyphs) {1063 if (!header) {1064 if (metrics) {1065 metrics.data = null;1066 }1067 return;1068 }1069 font.pos = (font.start ? font.start : 0) + header.offset;1070 font.pos += header.length - 2;1071 var numOfMetrics = font.getUint16();1072 if (numOfMetrics > numGlyphs) {1073 (0, _util.info)('The numOfMetrics (' + numOfMetrics + ') should not be ' + 'greater than the numGlyphs (' + numGlyphs + ')');1074 numOfMetrics = numGlyphs;1075 header.data[34] = (numOfMetrics & 0xff00) >> 8;1076 header.data[35] = numOfMetrics & 0x00ff;1077 }1078 var numOfSidebearings = numGlyphs - numOfMetrics;1079 var numMissing = numOfSidebearings - (metrics.length - numOfMetrics * 4 >> 1);1080 if (numMissing > 0) {1081 var entries = new Uint8Array(metrics.length + numMissing * 2);1082 entries.set(metrics.data);1083 metrics.data = entries;1084 }1085 }1086 function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart, hintsValid) {1087 var glyphProfile = {1088 length: 0,1089 sizeOfInstructions: 01090 };1091 if (sourceEnd - sourceStart <= 12) {1092 return glyphProfile;1093 }1094 var glyf = source.subarray(sourceStart, sourceEnd);1095 var contoursCount = signedInt16(glyf[0], glyf[1]);1096 if (contoursCount < 0) {1097 contoursCount = -1;1098 writeSignedInt16(glyf, 0, contoursCount);1099 dest.set(glyf, destStart);1100 glyphProfile.length = glyf.length;1101 return glyphProfile;1102 }1103 var i,1104 j = 10,1105 flagsCount = 0;1106 for (i = 0; i < contoursCount; i++) {1107 var endPoint = glyf[j] << 8 | glyf[j + 1];1108 flagsCount = endPoint + 1;1109 j += 2;1110 }1111 var instructionsStart = j;1112 var instructionsLength = glyf[j] << 8 | glyf[j + 1];1113 glyphProfile.sizeOfInstructions = instructionsLength;1114 j += 2 + instructionsLength;1115 var instructionsEnd = j;1116 var coordinatesLength = 0;1117 for (i = 0; i < flagsCount; i++) {1118 var flag = glyf[j++];1119 if (flag & 0xC0) {1120 glyf[j - 1] = flag & 0x3F;1121 }1122 var xyLength = (flag & 2 ? 1 : flag & 16 ? 0 : 2) + (flag & 4 ? 1 : flag & 32 ? 0 : 2);1123 coordinatesLength += xyLength;1124 if (flag & 8) {1125 var repeat = glyf[j++];1126 i += repeat;1127 coordinatesLength += repeat * xyLength;1128 }1129 }1130 if (coordinatesLength === 0) {1131 return glyphProfile;1132 }1133 var glyphDataLength = j + coordinatesLength;1134 if (glyphDataLength > glyf.length) {1135 return glyphProfile;1136 }1137 if (!hintsValid && instructionsLength > 0) {1138 dest.set(glyf.subarray(0, instructionsStart), destStart);1139 dest.set([0, 0], destStart + instructionsStart);1140 dest.set(glyf.subarray(instructionsEnd, glyphDataLength), destStart + instructionsStart + 2);1141 glyphDataLength -= instructionsLength;1142 if (glyf.length - glyphDataLength > 3) {1143 glyphDataLength = glyphDataLength + 3 & ~3;1144 }1145 glyphProfile.length = glyphDataLength;1146 return glyphProfile;1147 }1148 if (glyf.length - glyphDataLength > 3) {1149 glyphDataLength = glyphDataLength + 3 & ~3;1150 dest.set(glyf.subarray(0, glyphDataLength), destStart);1151 glyphProfile.length = glyphDataLength;1152 return glyphProfile;1153 }1154 dest.set(glyf, destStart);1155 glyphProfile.length = glyf.length;1156 return glyphProfile;1157 }1158 function sanitizeHead(head, numGlyphs, locaLength) {1159 var data = head.data;1160 var version = int32(data[0], data[1], data[2], data[3]);1161 if (version >> 16 !== 1) {1162 (0, _util.info)('Attempting to fix invalid version in head table: ' + version);1163 data[0] = 0;1164 data[1] = 1;1165 data[2] = 0;1166 data[3] = 0;1167 }1168 var indexToLocFormat = int16(data[50], data[51]);1169 if (indexToLocFormat < 0 || indexToLocFormat > 1) {1170 (0, _util.info)('Attempting to fix invalid indexToLocFormat in head table: ' + indexToLocFormat);1171 var numGlyphsPlusOne = numGlyphs + 1;1172 if (locaLength === numGlyphsPlusOne << 1) {1173 data[50] = 0;1174 data[51] = 0;1175 } else if (locaLength === numGlyphsPlusOne << 2) {1176 data[50] = 0;1177 data[51] = 1;1178 } else {1179 throw new _util.FormatError('Could not fix indexToLocFormat: ' + indexToLocFormat);1180 }1181 }1182 }1183 function sanitizeGlyphLocations(loca, glyf, numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions) {1184 var itemSize, itemDecode, itemEncode;1185 if (isGlyphLocationsLong) {1186 itemSize = 4;1187 itemDecode = function fontItemDecodeLong(data, offset) {1188 return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];1189 };1190 itemEncode = function fontItemEncodeLong(data, offset, value) {1191 data[offset] = value >>> 24 & 0xFF;1192 data[offset + 1] = value >> 16 & 0xFF;1193 data[offset + 2] = value >> 8 & 0xFF;1194 data[offset + 3] = value & 0xFF;1195 };1196 } else {1197 itemSize = 2;1198 itemDecode = function fontItemDecode(data, offset) {1199 return data[offset] << 9 | data[offset + 1] << 1;1200 };1201 itemEncode = function fontItemEncode(data, offset, value) {1202 data[offset] = value >> 9 & 0xFF;1203 data[offset + 1] = value >> 1 & 0xFF;1204 };1205 }1206 var locaData = loca.data;1207 var locaDataSize = itemSize * (1 + numGlyphs);1208 if (locaData.length !== locaDataSize) {1209 locaData = new Uint8Array(locaDataSize);1210 locaData.set(loca.data.subarray(0, locaDataSize));1211 loca.data = locaData;1212 }1213 var oldGlyfData = glyf.data;1214 var oldGlyfDataLength = oldGlyfData.length;1215 var newGlyfData = new Uint8Array(oldGlyfDataLength);1216 var startOffset = itemDecode(locaData, 0);1217 var writeOffset = 0;1218 var missingGlyphs = Object.create(null);1219 itemEncode(locaData, 0, writeOffset);1220 var i, j;1221 var locaCount = dupFirstEntry ? numGlyphs - 1 : numGlyphs;1222 for (i = 0, j = itemSize; i < locaCount; i++, j += itemSize) {1223 var endOffset = itemDecode(locaData, j);1224 if (endOffset > oldGlyfDataLength && (oldGlyfDataLength + 3 & ~3) === endOffset) {1225 endOffset = oldGlyfDataLength;1226 }1227 if (endOffset > oldGlyfDataLength) {1228 startOffset = endOffset;1229 }1230 var glyphProfile = sanitizeGlyph(oldGlyfData, startOffset, endOffset, newGlyfData, writeOffset, hintsValid);1231 var newLength = glyphProfile.length;1232 if (newLength === 0) {1233 missingGlyphs[i] = true;1234 }1235 if (glyphProfile.sizeOfInstructions > maxSizeOfInstructions) {1236 maxSizeOfInstructions = glyphProfile.sizeOfInstructions;1237 }1238 writeOffset += newLength;1239 itemEncode(locaData, j, writeOffset);1240 startOffset = endOffset;1241 }1242 if (writeOffset === 0) {1243 var simpleGlyph = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]);1244 for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {1245 itemEncode(locaData, j, simpleGlyph.length);1246 }1247 glyf.data = simpleGlyph;1248 } else if (dupFirstEntry) {1249 var firstEntryLength = itemDecode(locaData, itemSize);1250 if (newGlyfData.length > firstEntryLength + writeOffset) {1251 glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset);1252 } else {1253 glyf.data = new Uint8Array(firstEntryLength + writeOffset);1254 glyf.data.set(newGlyfData.subarray(0, writeOffset));1255 }1256 glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset);1257 itemEncode(loca.data, locaData.length - itemSize, writeOffset + firstEntryLength);1258 } else {1259 glyf.data = newGlyfData.subarray(0, writeOffset);1260 }1261 return {1262 missingGlyphs: missingGlyphs,1263 maxSizeOfInstructions: maxSizeOfInstructions1264 };1265 }1266 function readPostScriptTable(post, properties, maxpNumGlyphs) {1267 var start = (font.start ? font.start : 0) + post.offset;1268 font.pos = start;1269 var length = post.length,1270 end = start + length;1271 var version = font.getInt32();1272 font.getBytes(28);1273 var glyphNames;1274 var valid = true;1275 var i;1276 switch (version) {1277 case 0x00010000:1278 glyphNames = MacStandardGlyphOrdering;1279 break;1280 case 0x00020000:1281 var numGlyphs = font.getUint16();1282 if (numGlyphs !== maxpNumGlyphs) {1283 valid = false;1284 break;1285 }1286 var glyphNameIndexes = [];1287 for (i = 0; i < numGlyphs; ++i) {1288 var index = font.getUint16();1289 if (index >= 32768) {1290 valid = false;1291 break;1292 }1293 glyphNameIndexes.push(index);1294 }1295 if (!valid) {1296 break;1297 }1298 var customNames = [];1299 var strBuf = [];1300 while (font.pos < end) {1301 var stringLength = font.getByte();1302 strBuf.length = stringLength;1303 for (i = 0; i < stringLength; ++i) {1304 strBuf[i] = String.fromCharCode(font.getByte());1305 }1306 customNames.push(strBuf.join(''));1307 }1308 glyphNames = [];1309 for (i = 0; i < numGlyphs; ++i) {1310 var j = glyphNameIndexes[i];1311 if (j < 258) {1312 glyphNames.push(MacStandardGlyphOrdering[j]);1313 continue;1314 }1315 glyphNames.push(customNames[j - 258]);1316 }1317 break;1318 case 0x00030000:1319 break;1320 default:1321 (0, _util.warn)('Unknown/unsupported post table version ' + version);1322 valid = false;1323 if (properties.defaultEncoding) {1324 glyphNames = properties.defaultEncoding;1325 }1326 break;1327 }1328 properties.glyphNames = glyphNames;1329 return valid;1330 }1331 function readNameTable(nameTable) {1332 var start = (font.start ? font.start : 0) + nameTable.offset;1333 font.pos = start;1334 var names = [[], []];1335 var length = nameTable.length,1336 end = start + length;1337 var format = font.getUint16();1338 var FORMAT_0_HEADER_LENGTH = 6;1339 if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) {1340 return names;1341 }1342 var numRecords = font.getUint16();1343 var stringsStart = font.getUint16();1344 var records = [];1345 var NAME_RECORD_LENGTH = 12;1346 var i, ii;1347 for (i = 0; i < numRecords && font.pos + NAME_RECORD_LENGTH <= end; i++) {1348 var r = {1349 platform: font.getUint16(),1350 encoding: font.getUint16(),1351 language: font.getUint16(),1352 name: font.getUint16(),1353 length: font.getUint16(),1354 offset: font.getUint16()1355 };1356 if (r.platform === 1 && r.encoding === 0 && r.language === 0 || r.platform === 3 && r.encoding === 1 && r.language === 0x409) {1357 records.push(r);1358 }1359 }1360 for (i = 0, ii = records.length; i < ii; i++) {1361 var record = records[i];1362 if (record.length <= 0) {1363 continue;1364 }1365 var pos = start + stringsStart + record.offset;1366 if (pos + record.length > end) {1367 continue;1368 }1369 font.pos = pos;1370 var nameIndex = record.name;1371 if (record.encoding) {1372 var str = '';1373 for (var j = 0, jj = record.length; j < jj; j += 2) {1374 str += String.fromCharCode(font.getUint16());1375 }1376 names[1][nameIndex] = str;1377 } else {1378 names[0][nameIndex] = (0, _util.bytesToString)(font.getBytes(record.length));1379 }1380 }1381 return names;1382 }1383 var 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];1384 function sanitizeTTProgram(table, ttContext) {1385 var data = table.data;1386 var i = 0,1387 j,1388 n,1389 b,1390 funcId,1391 pc,1392 lastEndf = 0,1393 lastDeff = 0;1394 var stack = [];1395 var callstack = [];1396 var functionsCalled = [];1397 var tooComplexToFollowFunctions = ttContext.tooComplexToFollowFunctions;1398 var inFDEF = false,1399 ifLevel = 0,1400 inELSE = 0;1401 for (var ii = data.length; i < ii;) {1402 var op = data[i++];1403 if (op === 0x40) {1404 n = data[i++];1405 if (inFDEF || inELSE) {1406 i += n;1407 } else {1408 for (j = 0; j < n; j++) {1409 stack.push(data[i++]);1410 }1411 }1412 } else if (op === 0x41) {1413 n = data[i++];1414 if (inFDEF || inELSE) {1415 i += n * 2;1416 } else {1417 for (j = 0; j < n; j++) {1418 b = data[i++];1419 stack.push(b << 8 | data[i++]);1420 }1421 }1422 } else if ((op & 0xF8) === 0xB0) {1423 n = op - 0xB0 + 1;1424 if (inFDEF || inELSE) {1425 i += n;1426 } else {1427 for (j = 0; j < n; j++) {1428 stack.push(data[i++]);1429 }1430 }1431 } else if ((op & 0xF8) === 0xB8) {1432 n = op - 0xB8 + 1;1433 if (inFDEF || inELSE) {1434 i += n * 2;1435 } else {1436 for (j = 0; j < n; j++) {1437 b = data[i++];1438 stack.push(b << 8 | data[i++]);1439 }1440 }1441 } else if (op === 0x2B && !tooComplexToFollowFunctions) {1442 if (!inFDEF && !inELSE) {1443 funcId = stack[stack.length - 1];1444 ttContext.functionsUsed[funcId] = true;1445 if (funcId in ttContext.functionsStackDeltas) {1446 stack.length += ttContext.functionsStackDeltas[funcId];1447 } else if (funcId in ttContext.functionsDefined && functionsCalled.indexOf(funcId) < 0) {1448 callstack.push({1449 data: data,1450 i: i,1451 stackTop: stack.length - 11452 });1453 functionsCalled.push(funcId);1454 pc = ttContext.functionsDefined[funcId];1455 if (!pc) {1456 (0, _util.warn)('TT: CALL non-existent function');1457 ttContext.hintsValid = false;1458 return;1459 }1460 data = pc.data;1461 i = pc.i;1462 }1463 }1464 } else if (op === 0x2C && !tooComplexToFollowFunctions) {1465 if (inFDEF || inELSE) {1466 (0, _util.warn)('TT: nested FDEFs not allowed');1467 tooComplexToFollowFunctions = true;1468 }1469 inFDEF = true;1470 lastDeff = i;1471 funcId = stack.pop();1472 ttContext.functionsDefined[funcId] = {1473 data: data,1474 i: i1475 };1476 } else if (op === 0x2D) {1477 if (inFDEF) {1478 inFDEF = false;1479 lastEndf = i;1480 } else {1481 pc = callstack.pop();1482 if (!pc) {1483 (0, _util.warn)('TT: ENDF bad stack');1484 ttContext.hintsValid = false;1485 return;1486 }1487 funcId = functionsCalled.pop();1488 data = pc.data;1489 i = pc.i;1490 ttContext.functionsStackDeltas[funcId] = stack.length - pc.stackTop;1491 }1492 } else if (op === 0x89) {1493 if (inFDEF || inELSE) {1494 (0, _util.warn)('TT: nested IDEFs not allowed');1495 tooComplexToFollowFunctions = true;1496 }1497 inFDEF = true;1498 lastDeff = i;1499 } else if (op === 0x58) {1500 ++ifLevel;1501 } else if (op === 0x1B) {1502 inELSE = ifLevel;1503 } else if (op === 0x59) {1504 if (inELSE === ifLevel) {1505 inELSE = 0;1506 }1507 --ifLevel;1508 } else if (op === 0x1C) {1509 if (!inFDEF && !inELSE) {1510 var offset = stack[stack.length - 1];1511 if (offset > 0) {1512 i += offset - 1;1513 }1514 }1515 }1516 if (!inFDEF && !inELSE) {1517 var stackDelta = op <= 0x8E ? TTOpsStackDeltas[op] : op >= 0xC0 && op <= 0xDF ? -1 : op >= 0xE0 ? -2 : 0;1518 if (op >= 0x71 && op <= 0x75) {1519 n = stack.pop();1520 if (!isNaN(n)) {1521 stackDelta = -n * 2;1522 }1523 }1524 while (stackDelta < 0 && stack.length > 0) {1525 stack.pop();1526 stackDelta++;1527 }1528 while (stackDelta > 0) {1529 stack.push(NaN);1530 stackDelta--;1531 }1532 }1533 }1534 ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions;1535 var content = [data];1536 if (i > data.length) {1537 content.push(new Uint8Array(i - data.length));1538 }1539 if (lastDeff > lastEndf) {1540 (0, _util.warn)('TT: complementing a missing function tail');1541 content.push(new Uint8Array([0x22, 0x2D]));1542 }1543 foldTTTable(table, content);1544 }1545 function checkInvalidFunctions(ttContext, maxFunctionDefs) {1546 if (ttContext.tooComplexToFollowFunctions) {1547 return;1548 }1549 if (ttContext.functionsDefined.length > maxFunctionDefs) {1550 (0, _util.warn)('TT: more functions defined than expected');1551 ttContext.hintsValid = false;1552 return;1553 }1554 for (var j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) {1555 if (j > maxFunctionDefs) {1556 (0, _util.warn)('TT: invalid function id: ' + j);1557 ttContext.hintsValid = false;1558 return;1559 }1560 if (ttContext.functionsUsed[j] && !ttContext.functionsDefined[j]) {1561 (0, _util.warn)('TT: undefined function: ' + j);1562 ttContext.hintsValid = false;1563 return;1564 }1565 }1566 }1567 function foldTTTable(table, content) {1568 if (content.length > 1) {1569 var newLength = 0;1570 var j, jj;1571 for (j = 0, jj = content.length; j < jj; j++) {1572 newLength += content[j].length;1573 }1574 newLength = newLength + 3 & ~3;1575 var result = new Uint8Array(newLength);1576 var pos = 0;1577 for (j = 0, jj = content.length; j < jj; j++) {1578 result.set(content[j], pos);1579 pos += content[j].length;1580 }1581 table.data = result;1582 table.length = newLength;1583 }1584 }1585 function sanitizeTTPrograms(fpgm, prep, cvt, maxFunctionDefs) {1586 var ttContext = {1587 functionsDefined: [],1588 functionsUsed: [],1589 functionsStackDeltas: [],1590 tooComplexToFollowFunctions: false,1591 hintsValid: true1592 };1593 if (fpgm) {1594 sanitizeTTProgram(fpgm, ttContext);1595 }1596 if (prep) {1597 sanitizeTTProgram(prep, ttContext);1598 }1599 if (fpgm) {1600 checkInvalidFunctions(ttContext, maxFunctionDefs);1601 }1602 if (cvt && cvt.length & 1) {1603 var cvtData = new Uint8Array(cvt.length + 1);1604 cvtData.set(cvt.data);1605 cvt.data = cvtData;1606 }1607 return ttContext.hintsValid;1608 }1609 font = new _stream.Stream(new Uint8Array(font.getBytes()));1610 var VALID_TABLES = ['OS/2', 'cmap', 'head', 'hhea', 'hmtx', 'maxp', 'name', 'post', 'loca', 'glyf', 'fpgm', 'prep', 'cvt ', 'CFF '];1611 var header = readOpenTypeHeader(font);1612 var numTables = header.numTables;1613 var cff, cffFile;1614 var tables = Object.create(null);1615 tables['OS/2'] = null;1616 tables['cmap'] = null;1617 tables['head'] = null;1618 tables['hhea'] = null;1619 tables['hmtx'] = null;1620 tables['maxp'] = null;1621 tables['name'] = null;1622 tables['post'] = null;1623 var table;1624 for (var i = 0; i < numTables; i++) {1625 table = readTableEntry(font);1626 if (VALID_TABLES.indexOf(table.tag) < 0) {1627 continue;1628 }1629 if (table.length === 0) {1630 continue;1631 }1632 tables[table.tag] = table;1633 }1634 var isTrueType = !tables['CFF '];1635 if (!isTrueType) {1636 if (header.version === 'OTTO' && !(properties.composite && properties.cidToGidMap) || !tables['head'] || !tables['hhea'] || !tables['maxp'] || !tables['post']) {1637 cffFile = new _stream.Stream(tables['CFF '].data);1638 cff = new CFFFont(cffFile, properties);1639 adjustWidths(properties);1640 return this.convert(name, cff, properties);1641 }1642 delete tables['glyf'];1643 delete tables['loca'];1644 delete tables['fpgm'];1645 delete tables['prep'];1646 delete tables['cvt '];1647 this.isOpenType = true;1648 } else {1649 if (!tables['loca']) {1650 throw new _util.FormatError('Required "loca" table is not found');1651 }1652 if (!tables['glyf']) {1653 (0, _util.warn)('Required "glyf" table is not found -- trying to recover.');1654 tables['glyf'] = {1655 tag: 'glyf',1656 data: new Uint8Array(0)1657 };1658 }1659 this.isOpenType = false;1660 }1661 if (!tables['maxp']) {1662 throw new _util.FormatError('Required "maxp" table is not found');1663 }1664 font.pos = (font.start || 0) + tables['maxp'].offset;1665 var version = font.getInt32();1666 var numGlyphs = font.getUint16();1667 var maxFunctionDefs = 0;1668 var maxSizeOfInstructions = 0;1669 if (version >= 0x00010000 && tables['maxp'].length >= 22) {1670 font.pos += 8;1671 var maxZones = font.getUint16();1672 if (maxZones > 2) {1673 tables['maxp'].data[14] = 0;1674 tables['maxp'].data[15] = 2;1675 }1676 font.pos += 4;1677 maxFunctionDefs = font.getUint16();1678 font.pos += 6;1679 maxSizeOfInstructions = font.getUint16();1680 }1681 var dupFirstEntry = false;1682 if (properties.type === 'CIDFontType2' && properties.toUnicode && properties.toUnicode.get(0) > '\0') {1683 dupFirstEntry = true;1684 numGlyphs++;1685 tables['maxp'].data[4] = numGlyphs >> 8;1686 tables['maxp'].data[5] = numGlyphs & 255;1687 }1688 var hintsValid = sanitizeTTPrograms(tables['fpgm'], tables['prep'], tables['cvt '], maxFunctionDefs);1689 if (!hintsValid) {1690 delete tables['fpgm'];1691 delete tables['prep'];1692 delete tables['cvt '];1693 }1694 sanitizeMetrics(font, tables['hhea'], tables['hmtx'], numGlyphs);1695 if (!tables['head']) {1696 throw new _util.FormatError('Required "head" table is not found');1697 }1698 sanitizeHead(tables['head'], numGlyphs, isTrueType ? tables['loca'].length : 0);1699 var missingGlyphs = Object.create(null);1700 if (isTrueType) {1701 var isGlyphLocationsLong = int16(tables['head'].data[50], tables['head'].data[51]);1702 var glyphsInfo = sanitizeGlyphLocations(tables['loca'], tables['glyf'], numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions);1703 missingGlyphs = glyphsInfo.missingGlyphs;1704 if (version >= 0x00010000 && tables['maxp'].length >= 22) {1705 tables['maxp'].data[26] = glyphsInfo.maxSizeOfInstructions >> 8;1706 tables['maxp'].data[27] = glyphsInfo.maxSizeOfInstructions & 255;1707 }1708 }1709 if (!tables['hhea']) {1710 throw new _util.FormatError('Required "hhea" table is not found');1711 }1712 if (tables['hhea'].data[10] === 0 && tables['hhea'].data[11] === 0) {1713 tables['hhea'].data[10] = 0xFF;1714 tables['hhea'].data[11] = 0xFF;1715 }1716 var metricsOverride = {1717 unitsPerEm: int16(tables['head'].data[18], tables['head'].data[19]),1718 yMax: int16(tables['head'].data[42], tables['head'].data[43]),1719 yMin: signedInt16(tables['head'].data[38], tables['head'].data[39]),1720 ascent: int16(tables['hhea'].data[4], tables['hhea'].data[5]),1721 descent: signedInt16(tables['hhea'].data[6], tables['hhea'].data[7])1722 };1723 this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm;1724 this.descent = metricsOverride.descent / metricsOverride.unitsPerEm;1725 if (tables['post']) {1726 var valid = readPostScriptTable(tables['post'], properties, numGlyphs);1727 if (!valid) {1728 tables['post'] = null;1729 }1730 }1731 var charCodeToGlyphId = [],1732 charCode;1733 function hasGlyph(glyphId) {1734 return !missingGlyphs[glyphId];1735 }1736 if (properties.composite) {1737 var cidToGidMap = properties.cidToGidMap || [];1738 var isCidToGidMapEmpty = cidToGidMap.length === 0;1739 properties.cMap.forEach(function (charCode, cid) {1740 if (cid > 0xffff) {1741 throw new _util.FormatError('Max size of CID is 65,535');1742 }1743 var glyphId = -1;1744 if (isCidToGidMapEmpty) {1745 glyphId = cid;1746 } else if (cidToGidMap[cid] !== undefined) {1747 glyphId = cidToGidMap[cid];1748 }1749 if (glyphId >= 0 && glyphId < numGlyphs && hasGlyph(glyphId)) {1750 charCodeToGlyphId[charCode] = glyphId;1751 }1752 });1753 if (dupFirstEntry && (isCidToGidMapEmpty || !charCodeToGlyphId[0])) {1754 charCodeToGlyphId[0] = numGlyphs - 1;1755 }1756 } else {1757 var cmapTable = readCmapTable(tables['cmap'], font, this.isSymbolicFont, properties.hasEncoding);1758 var cmapPlatformId = cmapTable.platformId;1759 var cmapEncodingId = cmapTable.encodingId;1760 var cmapMappings = cmapTable.mappings;1761 var cmapMappingsLength = cmapMappings.length;1762 if (properties.hasEncoding && (cmapPlatformId === 3 && cmapEncodingId === 1 || cmapPlatformId === 1 && cmapEncodingId === 0) || cmapPlatformId === -1 && cmapEncodingId === -1 && !!(0, _encodings.getEncoding)(properties.baseEncodingName)) {1763 var baseEncoding = [];1764 if (properties.baseEncodingName === 'MacRomanEncoding' || properties.baseEncodingName === 'WinAnsiEncoding') {1765 baseEncoding = (0, _encodings.getEncoding)(properties.baseEncodingName);1766 }1767 var glyphsUnicodeMap = (0, _glyphlist.getGlyphsUnicode)();1768 for (charCode = 0; charCode < 256; charCode++) {1769 var glyphName, standardGlyphName;1770 if (this.differences && charCode in this.differences) {1771 glyphName = this.differences[charCode];1772 } else if (charCode in baseEncoding && baseEncoding[charCode] !== '') {1773 glyphName = baseEncoding[charCode];1774 } else {1775 glyphName = _encodings.StandardEncoding[charCode];1776 }1777 if (!glyphName) {1778 continue;1779 }1780 standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap);1781 var unicodeOrCharCode;1782 if (cmapPlatformId === 3 && cmapEncodingId === 1) {1783 unicodeOrCharCode = glyphsUnicodeMap[standardGlyphName];1784 } else if (cmapPlatformId === 1 && cmapEncodingId === 0) {1785 unicodeOrCharCode = _encodings.MacRomanEncoding.indexOf(standardGlyphName);1786 }1787 var found = false;1788 for (i = 0; i < cmapMappingsLength; ++i) {1789 if (cmapMappings[i].charCode !== unicodeOrCharCode) {1790 continue;1791 }1792 charCodeToGlyphId[charCode] = cmapMappings[i].glyphId;1793 found = true;1794 break;1795 }1796 if (!found && properties.glyphNames) {1797 var glyphId = properties.glyphNames.indexOf(glyphName);1798 if (glyphId === -1 && standardGlyphName !== glyphName) {1799 glyphId = properties.glyphNames.indexOf(standardGlyphName);1800 }1801 if (glyphId > 0 && hasGlyph(glyphId)) {1802 charCodeToGlyphId[charCode] = glyphId;1803 found = true;1804 }1805 }1806 }1807 } else if (cmapPlatformId === 0 && cmapEncodingId === 0) {1808 for (i = 0; i < cmapMappingsLength; ++i) {1809 charCodeToGlyphId[cmapMappings[i].charCode] = cmapMappings[i].glyphId;1810 }1811 } else {1812 for (i = 0; i < cmapMappingsLength; ++i) {1813 charCode = cmapMappings[i].charCode;1814 if (cmapPlatformId === 3 && charCode >= 0xF000 && charCode <= 0xF0FF) {1815 charCode &= 0xFF;1816 }1817 charCodeToGlyphId[charCode] = cmapMappings[i].glyphId;1818 }1819 }1820 }1821 if (charCodeToGlyphId.length === 0) {1822 charCodeToGlyphId[0] = 0;1823 }1824 var newMapping = adjustMapping(charCodeToGlyphId, properties, missingGlyphs);1825 this.toFontChar = newMapping.toFontChar;1826 tables['cmap'] = {1827 tag: 'cmap',1828 data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphs)1829 };1830 if (!tables['OS/2'] || !validateOS2Table(tables['OS/2'])) {1831 tables['OS/2'] = {1832 tag: 'OS/2',1833 data: createOS2Table(properties, newMapping.charCodeToGlyphId, metricsOverride)1834 };1835 }1836 if (!tables['post']) {1837 tables['post'] = {1838 tag: 'post',1839 data: createPostTable(properties)1840 };1841 }1842 if (!isTrueType) {1843 try {1844 cffFile = new _stream.Stream(tables['CFF '].data);1845 var parser = new _cff_parser.CFFParser(cffFile, properties, SEAC_ANALYSIS_ENABLED);1846 cff = parser.parse();1847 var compiler = new _cff_parser.CFFCompiler(cff);1848 tables['CFF '].data = compiler.compile();1849 } catch (e) {1850 (0, _util.warn)('Failed to compile font ' + properties.loadedName);1851 }1852 }1853 if (!tables['name']) {1854 tables['name'] = {1855 tag: 'name',1856 data: createNameTable(this.name)1857 };1858 } else {1859 var namePrototype = readNameTable(tables['name']);1860 tables['name'].data = createNameTable(name, namePrototype);1861 }1862 var builder = new OpenTypeFileBuilder(header.version);1863 for (var tableTag in tables) {1864 builder.addTable(tableTag, tables[tableTag].data);1865 }1866 return builder.toArray();1867 },1868 convert: function Font_convert(fontName, font, properties) {1869 properties.fixedPitch = false;1870 if (properties.builtInEncoding) {1871 adjustToUnicode(properties, properties.builtInEncoding);1872 }1873 var mapping = font.getGlyphMapping(properties);1874 var newMapping = adjustMapping(mapping, properties, Object.create(null));1875 this.toFontChar = newMapping.toFontChar;1876 var numGlyphs = font.numGlyphs;1877 function getCharCodes(charCodeToGlyphId, glyphId) {1878 var charCodes = null;1879 for (var charCode in charCodeToGlyphId) {1880 if (glyphId === charCodeToGlyphId[charCode]) {1881 if (!charCodes) {1882 charCodes = [];1883 }1884 charCodes.push(charCode | 0);1885 }1886 }1887 return charCodes;1888 }1889 function createCharCode(charCodeToGlyphId, glyphId) {1890 for (var charCode in charCodeToGlyphId) {1891 if (glyphId === charCodeToGlyphId[charCode]) {1892 return charCode | 0;1893 }1894 }1895 newMapping.charCodeToGlyphId[newMapping.nextAvailableFontCharCode] = glyphId;1896 return newMapping.nextAvailableFontCharCode++;1897 }1898 var seacs = font.seacs;1899 if (SEAC_ANALYSIS_ENABLED && seacs && seacs.length) {1900 var matrix = properties.fontMatrix || _util.FONT_IDENTITY_MATRIX;1901 var charset = font.getCharset();1902 var seacMap = Object.create(null);1903 for (var glyphId in seacs) {1904 glyphId |= 0;1905 var seac = seacs[glyphId];1906 var baseGlyphName = _encodings.StandardEncoding[seac[2]];1907 var accentGlyphName = _encodings.StandardEncoding[seac[3]];1908 var baseGlyphId = charset.indexOf(baseGlyphName);1909 var accentGlyphId = charset.indexOf(accentGlyphName);1910 if (baseGlyphId < 0 || accentGlyphId < 0) {1911 continue;1912 }1913 var accentOffset = {1914 x: seac[0] * matrix[0] + seac[1] * matrix[2] + matrix[4],1915 y: seac[0] * matrix[1] + seac[1] * matrix[3] + matrix[5]1916 };1917 var charCodes = getCharCodes(mapping, glyphId);1918 if (!charCodes) {1919 continue;1920 }1921 for (var i = 0, ii = charCodes.length; i < ii; i++) {1922 var charCode = charCodes[i];1923 var charCodeToGlyphId = newMapping.charCodeToGlyphId;1924 var baseFontCharCode = createCharCode(charCodeToGlyphId, baseGlyphId);1925 var accentFontCharCode = createCharCode(charCodeToGlyphId, accentGlyphId);1926 seacMap[charCode] = {1927 baseFontCharCode: baseFontCharCode,1928 accentFontCharCode: accentFontCharCode,1929 accentOffset: accentOffset1930 };1931 }1932 }1933 properties.seacMap = seacMap;1934 }1935 var unitsPerEm = 1 / (properties.fontMatrix || _util.FONT_IDENTITY_MATRIX)[0];1936 var builder = new OpenTypeFileBuilder('\x4F\x54\x54\x4F');1937 builder.addTable('CFF ', font.data);1938 builder.addTable('OS/2', createOS2Table(properties, newMapping.charCodeToGlyphId));1939 builder.addTable('cmap', createCmapTable(newMapping.charCodeToGlyphId, numGlyphs));1940 builder.addTable('head', '\x00\x01\x00\x00' + '\x00\x00\x10\x00' + '\x00\x00\x00\x00' + '\x5F\x0F\x3C\xF5' + '\x00\x00' + safeString16(unitsPerEm) + '\x00\x00\x00\x00\x9e\x0b\x7e\x27' + '\x00\x00\x00\x00\x9e\x0b\x7e\x27' + '\x00\x00' + safeString16(properties.descent) + '\x0F\xFF' + safeString16(properties.ascent) + string16(properties.italicAngle ? 2 : 0) + '\x00\x11' + '\x00\x00' + '\x00\x00' + '\x00\x00');1941 builder.addTable('hhea', '\x00\x01\x00\x00' + safeString16(properties.ascent) + safeString16(properties.descent) + '\x00\x00' + '\xFF\xFF' + '\x00\x00' + '\x00\x00' + '\x00\x00' + safeString16(properties.capHeight) + safeString16(Math.tan(properties.italicAngle) * properties.xHeight) + '\x00\x00' + '\x00\x00' + '\x00\x00' + '\x00\x00' + '\x00\x00' + '\x00\x00' + string16(numGlyphs));1942 builder.addTable('hmtx', function fontFieldsHmtx() {1943 var charstrings = font.charstrings;1944 var cffWidths = font.cff ? font.cff.widths : null;1945 var hmtx = '\x00\x00\x00\x00';1946 for (var i = 1, ii = numGlyphs; i < ii; i++) {1947 var width = 0;1948 if (charstrings) {1949 var charstring = charstrings[i - 1];1950 width = 'width' in charstring ? charstring.width : 0;1951 } else if (cffWidths) {1952 width = Math.ceil(cffWidths[i] || 0);1953 }1954 hmtx += string16(width) + string16(0);1955 }...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const wptools = require('wptools');2wptools.safeString16('test');3const wptools = require('wptools');4wptools.safeString16('test');5const wptools = require('wptools');6wptools.safeString16('test');7const wptools = require('wptools');8wptools.safeString16('test');9const wptools = require('wptools');10wptools.safeString16('test');

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptools = require('wptools');2var wiki = wptools.page('Albert Einstein');3wiki.safeString16(function(err, response){4 console.log(response);5});6var wptools = require('wptools');7var wiki = wptools.page('Albert Einstein');8wiki.safeString16(function(err, response){9 console.log(response);10});

Full Screen

Using AI Code Generation

copy

Full Screen

1var text = "I'm a string with a quote (') and a double quote (\")";2var safe = wptexturize.safeString16(text);3console.log(safe);4var text = "I'm a string with a quote (') and a double quote (\")";5var safe = wptexturize.safeString16(text);6console.log(safe);

Full Screen

Using AI Code Generation

copy

Full Screen

1var myString = "hello world!";2var mySafeString = wptextutils.safeString16(myString);3alert(mySafeString);4var myString = "hello world!";5var mySafeString = wptextutils.safeString32(myString);6alert(mySafeString);7var myString = "hello world!";8var mySafeString = wptextutils.safeString64(myString);9alert(mySafeString);10var myString = "hello world!";11var mySafeString = wptextutils.safeString128(myString);12alert(mySafeString);13var myString = "hello world!";14var mySafeString = wptextutils.safeString256(myString);15alert(mySafeString);

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run wpt automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful