How to use readTrueTypeCollectionData method in wpt

Best JavaScript code snippet using wpt

fonts.js

Source:fonts.js Github

copy

Full Screen

...963 return header;964 }965 throw new _util.FormatError('Invalid TrueType Collection majorVersion: ' + majorVersion + '.');966 }967 function readTrueTypeCollectionData(ttc, fontName) {968 var _readTrueTypeCollecti = readTrueTypeCollectionHeader(ttc),969 numFonts = _readTrueTypeCollecti.numFonts,970 offsetTable = _readTrueTypeCollecti.offsetTable;971 for (var i = 0; i < numFonts; i++) {972 ttc.pos = (ttc.start || 0) + offsetTable[i];973 var potentialHeader = readOpenTypeHeader(ttc);974 var potentialTables = readTables(ttc, potentialHeader.numTables);975 if (!potentialTables['name']) {976 throw new _util.FormatError('TrueType Collection font must contain a "name" table.');977 }978 var nameTable = readNameTable(potentialTables['name']);979 for (var j = 0, jj = nameTable.length; j < jj; j++) {980 for (var k = 0, kk = nameTable[j].length; k < kk; k++) {981 var nameEntry = nameTable[j][k];982 if (nameEntry && nameEntry.replace(/\s/g, '') === fontName) {983 return {984 header: potentialHeader,985 tables: potentialTables986 };987 }988 }989 }990 }991 throw new _util.FormatError('TrueType Collection does not contain "' + fontName + '" font.');992 }993 function readCmapTable(cmap, font, isSymbolicFont, hasEncoding) {994 if (!cmap) {995 (0, _util.warn)('No cmap table available.');996 return {997 platformId: -1,998 encodingId: -1,999 mappings: [],1000 hasShortCmap: false1001 };1002 }1003 var segment;1004 var start = (font.start ? font.start : 0) + cmap.offset;1005 font.pos = start;1006 font.getUint16();1007 var numTables = font.getUint16();1008 var potentialTable;1009 var canBreak = false;1010 for (var i = 0; i < numTables; i++) {1011 var platformId = font.getUint16();1012 var encodingId = font.getUint16();1013 var offset = font.getInt32() >>> 0;1014 var useTable = false;1015 if (potentialTable && potentialTable.platformId === platformId && potentialTable.encodingId === encodingId) {1016 continue;1017 }1018 if (platformId === 0 && encodingId === 0) {1019 useTable = true;1020 } else if (platformId === 1 && encodingId === 0) {1021 useTable = true;1022 } else if (platformId === 3 && encodingId === 1 && (hasEncoding || !potentialTable)) {1023 useTable = true;1024 if (!isSymbolicFont) {1025 canBreak = true;1026 }1027 } else if (isSymbolicFont && platformId === 3 && encodingId === 0) {1028 useTable = true;1029 canBreak = true;1030 }1031 if (useTable) {1032 potentialTable = {1033 platformId: platformId,1034 encodingId: encodingId,1035 offset: offset1036 };1037 }1038 if (canBreak) {1039 break;1040 }1041 }1042 if (potentialTable) {1043 font.pos = start + potentialTable.offset;1044 }1045 if (!potentialTable || font.peekByte() === -1) {1046 (0, _util.warn)('Could not find a preferred cmap table.');1047 return {1048 platformId: -1,1049 encodingId: -1,1050 mappings: [],1051 hasShortCmap: false1052 };1053 }1054 var format = font.getUint16();1055 font.getUint16();1056 font.getUint16();1057 var hasShortCmap = false;1058 var mappings = [];1059 var j, glyphId;1060 if (format === 0) {1061 for (j = 0; j < 256; j++) {1062 var index = font.getByte();1063 if (!index) {1064 continue;1065 }1066 mappings.push({1067 charCode: j,1068 glyphId: index1069 });1070 }1071 hasShortCmap = true;1072 } else if (format === 4) {1073 var segCount = font.getUint16() >> 1;1074 font.getBytes(6);1075 var segIndex,1076 segments = [];1077 for (segIndex = 0; segIndex < segCount; segIndex++) {1078 segments.push({ end: font.getUint16() });1079 }1080 font.getUint16();1081 for (segIndex = 0; segIndex < segCount; segIndex++) {1082 segments[segIndex].start = font.getUint16();1083 }1084 for (segIndex = 0; segIndex < segCount; segIndex++) {1085 segments[segIndex].delta = font.getUint16();1086 }1087 var offsetsCount = 0;1088 for (segIndex = 0; segIndex < segCount; segIndex++) {1089 segment = segments[segIndex];1090 var rangeOffset = font.getUint16();1091 if (!rangeOffset) {1092 segment.offsetIndex = -1;1093 continue;1094 }1095 var offsetIndex = (rangeOffset >> 1) - (segCount - segIndex);1096 segment.offsetIndex = offsetIndex;1097 offsetsCount = Math.max(offsetsCount, offsetIndex + segment.end - segment.start + 1);1098 }1099 var offsets = [];1100 for (j = 0; j < offsetsCount; j++) {1101 offsets.push(font.getUint16());1102 }1103 for (segIndex = 0; segIndex < segCount; segIndex++) {1104 segment = segments[segIndex];1105 start = segment.start;1106 var end = segment.end;1107 var delta = segment.delta;1108 offsetIndex = segment.offsetIndex;1109 for (j = start; j <= end; j++) {1110 if (j === 0xFFFF) {1111 continue;1112 }1113 glyphId = offsetIndex < 0 ? j : offsets[offsetIndex + j - start];1114 glyphId = glyphId + delta & 0xFFFF;1115 mappings.push({1116 charCode: j,1117 glyphId: glyphId1118 });1119 }1120 }1121 } else if (format === 6) {1122 var firstCode = font.getUint16();1123 var entryCount = font.getUint16();1124 for (j = 0; j < entryCount; j++) {1125 glyphId = font.getUint16();1126 var charCode = firstCode + j;1127 mappings.push({1128 charCode: charCode,1129 glyphId: glyphId1130 });1131 }1132 } else {1133 (0, _util.warn)('cmap table has unsupported format: ' + format);1134 return {1135 platformId: -1,1136 encodingId: -1,1137 mappings: [],1138 hasShortCmap: false1139 };1140 }1141 mappings.sort(function (a, b) {1142 return a.charCode - b.charCode;1143 });1144 for (i = 1; i < mappings.length; i++) {1145 if (mappings[i - 1].charCode === mappings[i].charCode) {1146 mappings.splice(i, 1);1147 i--;1148 }1149 }1150 return {1151 platformId: potentialTable.platformId,1152 encodingId: potentialTable.encodingId,1153 mappings: mappings,1154 hasShortCmap: hasShortCmap1155 };1156 }1157 function sanitizeMetrics(font, header, metrics, numGlyphs) {1158 if (!header) {1159 if (metrics) {1160 metrics.data = null;1161 }1162 return;1163 }1164 font.pos = (font.start ? font.start : 0) + header.offset;1165 font.pos += header.length - 2;1166 var numOfMetrics = font.getUint16();1167 if (numOfMetrics > numGlyphs) {1168 (0, _util.info)('The numOfMetrics (' + numOfMetrics + ') should not be ' + 'greater than the numGlyphs (' + numGlyphs + ')');1169 numOfMetrics = numGlyphs;1170 header.data[34] = (numOfMetrics & 0xff00) >> 8;1171 header.data[35] = numOfMetrics & 0x00ff;1172 }1173 var numOfSidebearings = numGlyphs - numOfMetrics;1174 var numMissing = numOfSidebearings - (metrics.length - numOfMetrics * 4 >> 1);1175 if (numMissing > 0) {1176 var entries = new Uint8Array(metrics.length + numMissing * 2);1177 entries.set(metrics.data);1178 metrics.data = entries;1179 }1180 }1181 function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart, hintsValid) {1182 var glyphProfile = {1183 length: 0,1184 sizeOfInstructions: 01185 };1186 if (sourceEnd - sourceStart <= 12) {1187 return glyphProfile;1188 }1189 var glyf = source.subarray(sourceStart, sourceEnd);1190 var contoursCount = signedInt16(glyf[0], glyf[1]);1191 if (contoursCount < 0) {1192 contoursCount = -1;1193 writeSignedInt16(glyf, 0, contoursCount);1194 dest.set(glyf, destStart);1195 glyphProfile.length = glyf.length;1196 return glyphProfile;1197 }1198 var i,1199 j = 10,1200 flagsCount = 0;1201 for (i = 0; i < contoursCount; i++) {1202 var endPoint = glyf[j] << 8 | glyf[j + 1];1203 flagsCount = endPoint + 1;1204 j += 2;1205 }1206 var instructionsStart = j;1207 var instructionsLength = glyf[j] << 8 | glyf[j + 1];1208 glyphProfile.sizeOfInstructions = instructionsLength;1209 j += 2 + instructionsLength;1210 var instructionsEnd = j;1211 var coordinatesLength = 0;1212 for (i = 0; i < flagsCount; i++) {1213 var flag = glyf[j++];1214 if (flag & 0xC0) {1215 glyf[j - 1] = flag & 0x3F;1216 }1217 var xyLength = (flag & 2 ? 1 : flag & 16 ? 0 : 2) + (flag & 4 ? 1 : flag & 32 ? 0 : 2);1218 coordinatesLength += xyLength;1219 if (flag & 8) {1220 var repeat = glyf[j++];1221 i += repeat;1222 coordinatesLength += repeat * xyLength;1223 }1224 }1225 if (coordinatesLength === 0) {1226 return glyphProfile;1227 }1228 var glyphDataLength = j + coordinatesLength;1229 if (glyphDataLength > glyf.length) {1230 return glyphProfile;1231 }1232 if (!hintsValid && instructionsLength > 0) {1233 dest.set(glyf.subarray(0, instructionsStart), destStart);1234 dest.set([0, 0], destStart + instructionsStart);1235 dest.set(glyf.subarray(instructionsEnd, glyphDataLength), destStart + instructionsStart + 2);1236 glyphDataLength -= instructionsLength;1237 if (glyf.length - glyphDataLength > 3) {1238 glyphDataLength = glyphDataLength + 3 & ~3;1239 }1240 glyphProfile.length = glyphDataLength;1241 return glyphProfile;1242 }1243 if (glyf.length - glyphDataLength > 3) {1244 glyphDataLength = glyphDataLength + 3 & ~3;1245 dest.set(glyf.subarray(0, glyphDataLength), destStart);1246 glyphProfile.length = glyphDataLength;1247 return glyphProfile;1248 }1249 dest.set(glyf, destStart);1250 glyphProfile.length = glyf.length;1251 return glyphProfile;1252 }1253 function sanitizeHead(head, numGlyphs, locaLength) {1254 var data = head.data;1255 var version = int32(data[0], data[1], data[2], data[3]);1256 if (version >> 16 !== 1) {1257 (0, _util.info)('Attempting to fix invalid version in head table: ' + version);1258 data[0] = 0;1259 data[1] = 1;1260 data[2] = 0;1261 data[3] = 0;1262 }1263 var indexToLocFormat = int16(data[50], data[51]);1264 if (indexToLocFormat < 0 || indexToLocFormat > 1) {1265 (0, _util.info)('Attempting to fix invalid indexToLocFormat in head table: ' + indexToLocFormat);1266 var numGlyphsPlusOne = numGlyphs + 1;1267 if (locaLength === numGlyphsPlusOne << 1) {1268 data[50] = 0;1269 data[51] = 0;1270 } else if (locaLength === numGlyphsPlusOne << 2) {1271 data[50] = 0;1272 data[51] = 1;1273 } else {1274 throw new _util.FormatError('Could not fix indexToLocFormat: ' + indexToLocFormat);1275 }1276 }1277 }1278 function sanitizeGlyphLocations(loca, glyf, numGlyphs, isGlyphLocationsLong, hintsValid, dupFirstEntry, maxSizeOfInstructions) {1279 var itemSize, itemDecode, itemEncode;1280 if (isGlyphLocationsLong) {1281 itemSize = 4;1282 itemDecode = function fontItemDecodeLong(data, offset) {1283 return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];1284 };1285 itemEncode = function fontItemEncodeLong(data, offset, value) {1286 data[offset] = value >>> 24 & 0xFF;1287 data[offset + 1] = value >> 16 & 0xFF;1288 data[offset + 2] = value >> 8 & 0xFF;1289 data[offset + 3] = value & 0xFF;1290 };1291 } else {1292 itemSize = 2;1293 itemDecode = function fontItemDecode(data, offset) {1294 return data[offset] << 9 | data[offset + 1] << 1;1295 };1296 itemEncode = function fontItemEncode(data, offset, value) {1297 data[offset] = value >> 9 & 0xFF;1298 data[offset + 1] = value >> 1 & 0xFF;1299 };1300 }1301 var locaData = loca.data;1302 var locaDataSize = itemSize * (1 + numGlyphs);1303 if (locaData.length !== locaDataSize) {1304 locaData = new Uint8Array(locaDataSize);1305 locaData.set(loca.data.subarray(0, locaDataSize));1306 loca.data = locaData;1307 }1308 var oldGlyfData = glyf.data;1309 var oldGlyfDataLength = oldGlyfData.length;1310 var newGlyfData = new Uint8Array(oldGlyfDataLength);1311 var startOffset = itemDecode(locaData, 0);1312 var writeOffset = 0;1313 var missingGlyphs = Object.create(null);1314 itemEncode(locaData, 0, writeOffset);1315 var i, j;1316 var locaCount = dupFirstEntry ? numGlyphs - 1 : numGlyphs;1317 for (i = 0, j = itemSize; i < locaCount; i++, j += itemSize) {1318 var endOffset = itemDecode(locaData, j);1319 if (endOffset === 0) {1320 endOffset = startOffset;1321 }1322 if (endOffset > oldGlyfDataLength && (oldGlyfDataLength + 3 & ~3) === endOffset) {1323 endOffset = oldGlyfDataLength;1324 }1325 if (endOffset > oldGlyfDataLength) {1326 startOffset = endOffset;1327 }1328 var glyphProfile = sanitizeGlyph(oldGlyfData, startOffset, endOffset, newGlyfData, writeOffset, hintsValid);1329 var newLength = glyphProfile.length;1330 if (newLength === 0) {1331 missingGlyphs[i] = true;1332 }1333 if (glyphProfile.sizeOfInstructions > maxSizeOfInstructions) {1334 maxSizeOfInstructions = glyphProfile.sizeOfInstructions;1335 }1336 writeOffset += newLength;1337 itemEncode(locaData, j, writeOffset);1338 startOffset = endOffset;1339 }1340 if (writeOffset === 0) {1341 var simpleGlyph = new Uint8Array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]);1342 for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {1343 itemEncode(locaData, j, simpleGlyph.length);1344 }1345 glyf.data = simpleGlyph;1346 } else if (dupFirstEntry) {1347 var firstEntryLength = itemDecode(locaData, itemSize);1348 if (newGlyfData.length > firstEntryLength + writeOffset) {1349 glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset);1350 } else {1351 glyf.data = new Uint8Array(firstEntryLength + writeOffset);1352 glyf.data.set(newGlyfData.subarray(0, writeOffset));1353 }1354 glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset);1355 itemEncode(loca.data, locaData.length - itemSize, writeOffset + firstEntryLength);1356 } else {1357 glyf.data = newGlyfData.subarray(0, writeOffset);1358 }1359 return {1360 missingGlyphs: missingGlyphs,1361 maxSizeOfInstructions: maxSizeOfInstructions1362 };1363 }1364 function readPostScriptTable(post, properties, maxpNumGlyphs) {1365 var start = (font.start ? font.start : 0) + post.offset;1366 font.pos = start;1367 var length = post.length,1368 end = start + length;1369 var version = font.getInt32();1370 font.getBytes(28);1371 var glyphNames;1372 var valid = true;1373 var i;1374 switch (version) {1375 case 0x00010000:1376 glyphNames = MacStandardGlyphOrdering;1377 break;1378 case 0x00020000:1379 var numGlyphs = font.getUint16();1380 if (numGlyphs !== maxpNumGlyphs) {1381 valid = false;1382 break;1383 }1384 var glyphNameIndexes = [];1385 for (i = 0; i < numGlyphs; ++i) {1386 var index = font.getUint16();1387 if (index >= 32768) {1388 valid = false;1389 break;1390 }1391 glyphNameIndexes.push(index);1392 }1393 if (!valid) {1394 break;1395 }1396 var customNames = [];1397 var strBuf = [];1398 while (font.pos < end) {1399 var stringLength = font.getByte();1400 strBuf.length = stringLength;1401 for (i = 0; i < stringLength; ++i) {1402 strBuf[i] = String.fromCharCode(font.getByte());1403 }1404 customNames.push(strBuf.join(''));1405 }1406 glyphNames = [];1407 for (i = 0; i < numGlyphs; ++i) {1408 var j = glyphNameIndexes[i];1409 if (j < 258) {1410 glyphNames.push(MacStandardGlyphOrdering[j]);1411 continue;1412 }1413 glyphNames.push(customNames[j - 258]);1414 }1415 break;1416 case 0x00030000:1417 break;1418 default:1419 (0, _util.warn)('Unknown/unsupported post table version ' + version);1420 valid = false;1421 if (properties.defaultEncoding) {1422 glyphNames = properties.defaultEncoding;1423 }1424 break;1425 }1426 properties.glyphNames = glyphNames;1427 return valid;1428 }1429 function readNameTable(nameTable) {1430 var start = (font.start ? font.start : 0) + nameTable.offset;1431 font.pos = start;1432 var names = [[], []];1433 var length = nameTable.length,1434 end = start + length;1435 var format = font.getUint16();1436 var FORMAT_0_HEADER_LENGTH = 6;1437 if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) {1438 return names;1439 }1440 var numRecords = font.getUint16();1441 var stringsStart = font.getUint16();1442 var records = [];1443 var NAME_RECORD_LENGTH = 12;1444 var i, ii;1445 for (i = 0; i < numRecords && font.pos + NAME_RECORD_LENGTH <= end; i++) {1446 var r = {1447 platform: font.getUint16(),1448 encoding: font.getUint16(),1449 language: font.getUint16(),1450 name: font.getUint16(),1451 length: font.getUint16(),1452 offset: font.getUint16()1453 };1454 if (r.platform === 1 && r.encoding === 0 && r.language === 0 || r.platform === 3 && r.encoding === 1 && r.language === 0x409) {1455 records.push(r);1456 }1457 }1458 for (i = 0, ii = records.length; i < ii; i++) {1459 var record = records[i];1460 if (record.length <= 0) {1461 continue;1462 }1463 var pos = start + stringsStart + record.offset;1464 if (pos + record.length > end) {1465 continue;1466 }1467 font.pos = pos;1468 var nameIndex = record.name;1469 if (record.encoding) {1470 var str = '';1471 for (var j = 0, jj = record.length; j < jj; j += 2) {1472 str += String.fromCharCode(font.getUint16());1473 }1474 names[1][nameIndex] = str;1475 } else {1476 names[0][nameIndex] = (0, _util.bytesToString)(font.getBytes(record.length));1477 }1478 }1479 return names;1480 }1481 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];1482 function sanitizeTTProgram(table, ttContext) {1483 var data = table.data;1484 var i = 0,1485 j,1486 n,1487 b,1488 funcId,1489 pc,1490 lastEndf = 0,1491 lastDeff = 0;1492 var stack = [];1493 var callstack = [];1494 var functionsCalled = [];1495 var tooComplexToFollowFunctions = ttContext.tooComplexToFollowFunctions;1496 var inFDEF = false,1497 ifLevel = 0,1498 inELSE = 0;1499 for (var ii = data.length; i < ii;) {1500 var op = data[i++];1501 if (op === 0x40) {1502 n = data[i++];1503 if (inFDEF || inELSE) {1504 i += n;1505 } else {1506 for (j = 0; j < n; j++) {1507 stack.push(data[i++]);1508 }1509 }1510 } else if (op === 0x41) {1511 n = data[i++];1512 if (inFDEF || inELSE) {1513 i += n * 2;1514 } else {1515 for (j = 0; j < n; j++) {1516 b = data[i++];1517 stack.push(b << 8 | data[i++]);1518 }1519 }1520 } else if ((op & 0xF8) === 0xB0) {1521 n = op - 0xB0 + 1;1522 if (inFDEF || inELSE) {1523 i += n;1524 } else {1525 for (j = 0; j < n; j++) {1526 stack.push(data[i++]);1527 }1528 }1529 } else if ((op & 0xF8) === 0xB8) {1530 n = op - 0xB8 + 1;1531 if (inFDEF || inELSE) {1532 i += n * 2;1533 } else {1534 for (j = 0; j < n; j++) {1535 b = data[i++];1536 stack.push(b << 8 | data[i++]);1537 }1538 }1539 } else if (op === 0x2B && !tooComplexToFollowFunctions) {1540 if (!inFDEF && !inELSE) {1541 funcId = stack[stack.length - 1];1542 ttContext.functionsUsed[funcId] = true;1543 if (funcId in ttContext.functionsStackDeltas) {1544 stack.length += ttContext.functionsStackDeltas[funcId];1545 } else if (funcId in ttContext.functionsDefined && functionsCalled.indexOf(funcId) < 0) {1546 callstack.push({1547 data: data,1548 i: i,1549 stackTop: stack.length - 11550 });1551 functionsCalled.push(funcId);1552 pc = ttContext.functionsDefined[funcId];1553 if (!pc) {1554 (0, _util.warn)('TT: CALL non-existent function');1555 ttContext.hintsValid = false;1556 return;1557 }1558 data = pc.data;1559 i = pc.i;1560 }1561 }1562 } else if (op === 0x2C && !tooComplexToFollowFunctions) {1563 if (inFDEF || inELSE) {1564 (0, _util.warn)('TT: nested FDEFs not allowed');1565 tooComplexToFollowFunctions = true;1566 }1567 inFDEF = true;1568 lastDeff = i;1569 funcId = stack.pop();1570 ttContext.functionsDefined[funcId] = {1571 data: data,1572 i: i1573 };1574 } else if (op === 0x2D) {1575 if (inFDEF) {1576 inFDEF = false;1577 lastEndf = i;1578 } else {1579 pc = callstack.pop();1580 if (!pc) {1581 (0, _util.warn)('TT: ENDF bad stack');1582 ttContext.hintsValid = false;1583 return;1584 }1585 funcId = functionsCalled.pop();1586 data = pc.data;1587 i = pc.i;1588 ttContext.functionsStackDeltas[funcId] = stack.length - pc.stackTop;1589 }1590 } else if (op === 0x89) {1591 if (inFDEF || inELSE) {1592 (0, _util.warn)('TT: nested IDEFs not allowed');1593 tooComplexToFollowFunctions = true;1594 }1595 inFDEF = true;1596 lastDeff = i;1597 } else if (op === 0x58) {1598 ++ifLevel;1599 } else if (op === 0x1B) {1600 inELSE = ifLevel;1601 } else if (op === 0x59) {1602 if (inELSE === ifLevel) {1603 inELSE = 0;1604 }1605 --ifLevel;1606 } else if (op === 0x1C) {1607 if (!inFDEF && !inELSE) {1608 var offset = stack[stack.length - 1];1609 if (offset > 0) {1610 i += offset - 1;1611 }1612 }1613 }1614 if (!inFDEF && !inELSE) {1615 var stackDelta = op <= 0x8E ? TTOpsStackDeltas[op] : op >= 0xC0 && op <= 0xDF ? -1 : op >= 0xE0 ? -2 : 0;1616 if (op >= 0x71 && op <= 0x75) {1617 n = stack.pop();1618 if (!isNaN(n)) {1619 stackDelta = -n * 2;1620 }1621 }1622 while (stackDelta < 0 && stack.length > 0) {1623 stack.pop();1624 stackDelta++;1625 }1626 while (stackDelta > 0) {1627 stack.push(NaN);1628 stackDelta--;1629 }1630 }1631 }1632 ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions;1633 var content = [data];1634 if (i > data.length) {1635 content.push(new Uint8Array(i - data.length));1636 }1637 if (lastDeff > lastEndf) {1638 (0, _util.warn)('TT: complementing a missing function tail');1639 content.push(new Uint8Array([0x22, 0x2D]));1640 }1641 foldTTTable(table, content);1642 }1643 function checkInvalidFunctions(ttContext, maxFunctionDefs) {1644 if (ttContext.tooComplexToFollowFunctions) {1645 return;1646 }1647 if (ttContext.functionsDefined.length > maxFunctionDefs) {1648 (0, _util.warn)('TT: more functions defined than expected');1649 ttContext.hintsValid = false;1650 return;1651 }1652 for (var j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) {1653 if (j > maxFunctionDefs) {1654 (0, _util.warn)('TT: invalid function id: ' + j);1655 ttContext.hintsValid = false;1656 return;1657 }1658 if (ttContext.functionsUsed[j] && !ttContext.functionsDefined[j]) {1659 (0, _util.warn)('TT: undefined function: ' + j);1660 ttContext.hintsValid = false;1661 return;1662 }1663 }1664 }1665 function foldTTTable(table, content) {1666 if (content.length > 1) {1667 var newLength = 0;1668 var j, jj;1669 for (j = 0, jj = content.length; j < jj; j++) {1670 newLength += content[j].length;1671 }1672 newLength = newLength + 3 & ~3;1673 var result = new Uint8Array(newLength);1674 var pos = 0;1675 for (j = 0, jj = content.length; j < jj; j++) {1676 result.set(content[j], pos);1677 pos += content[j].length;1678 }1679 table.data = result;1680 table.length = newLength;1681 }1682 }1683 function sanitizeTTPrograms(fpgm, prep, cvt, maxFunctionDefs) {1684 var ttContext = {1685 functionsDefined: [],1686 functionsUsed: [],1687 functionsStackDeltas: [],1688 tooComplexToFollowFunctions: false,1689 hintsValid: true1690 };1691 if (fpgm) {1692 sanitizeTTProgram(fpgm, ttContext);1693 }1694 if (prep) {1695 sanitizeTTProgram(prep, ttContext);1696 }1697 if (fpgm) {1698 checkInvalidFunctions(ttContext, maxFunctionDefs);1699 }1700 if (cvt && cvt.length & 1) {1701 var cvtData = new Uint8Array(cvt.length + 1);1702 cvtData.set(cvt.data);1703 cvt.data = cvtData;1704 }1705 return ttContext.hintsValid;1706 }1707 font = new _stream.Stream(new Uint8Array(font.getBytes()));1708 var header = void 0,1709 tables = void 0;1710 if (isTrueTypeCollectionFile(font)) {1711 var ttcData = readTrueTypeCollectionData(font, this.name);1712 header = ttcData.header;1713 tables = ttcData.tables;1714 } else {1715 header = readOpenTypeHeader(font);1716 tables = readTables(font, header.numTables);1717 }1718 var cff = void 0,1719 cffFile = void 0;1720 var isTrueType = !tables['CFF '];1721 if (!isTrueType) {1722 if (header.version === 'OTTO' && !(properties.composite && properties.cidToGidMap) || !tables['head'] || !tables['hhea'] || !tables['maxp'] || !tables['post']) {1723 cffFile = new _stream.Stream(tables['CFF '].data);1724 cff = new CFFFont(cffFile, properties);1725 adjustWidths(properties);...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptt = require('wptt');2var fs = require('fs');3var buffer = fs.readFileSync('test.ttc');4var data = wptt.readTrueTypeCollectionData(buffer);5console.log(data);6var wptt = require('wptt');7var fs = require('fs');8var buffer = fs.readFileSync('test.ttf');9var data = wptt.readTrueTypeFontData(buffer);10console.log(data);11var wptt = require('wptt');12var fs = require('fs');13var buffer = fs.readFileSync('test.ttf');14var data = wptt.readTrueTypeData(buffer);15console.log(data);16### `readTrueTypeCollectionData(buffer)`17### `readTrueTypeFontData(buffer)`18### `readTrueTypeData(buffer)`19[MIT](LICENSE)

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptt = require('wptt');2wptt.readTrueTypeCollectionData('font.ttf', function(err, data) {3 if (err) throw err;4 console.log(data);5});6### wptt.readTrueTypeCollectionData(fontPath, callback)

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptt = require('wptt');2var fs = require('fs');3var buffer = fs.readFileSync('test.ttf');4wptt.readTrueTypeCollectionData(buffer, function(err, data) {5 if (err) {6 console.log(err);7 return;8 }9 console.log(data);10});

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptt = require('wptt');2var fs = require('fs');3var path = require('path');4var data = fs.readFileSync(path.join(__dirname, 'test.ttf'));5var ttcData = wptt.readTrueTypeCollectionData(data);6console.log('Number of fonts in collection: ' + ttcData.fonts.length);7console.log('Font names:');8for (var i = 0; i < ttcData.fonts.length; i++) {9 console.log('Font #' + i + ': ' + ttcData.fonts[i].name);10}11### readTrueTypeCollectionData(data)12 * `name`: Font name (string)13[MIT](LICENSE)

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