Best JavaScript code snippet using wpt
font_renderer.js
Source:font_renderer.js
...73 return ranges;74 }75 error('not supported cmap: ' + format);76 }77 function parseCff(data, start, end) {78 var properties = {};79 var parser = new CFFParser(new Stream(data, start, end - start),80 properties);81 var cff = parser.parse();82 return {83 glyphs: cff.charStrings.objects,84 subrs: (cff.topDict.privateDict && cff.topDict.privateDict.subrsIndex &&85 cff.topDict.privateDict.subrsIndex.objects),86 gsubrs: cff.globalSubrIndex && cff.globalSubrIndex.objects87 };88 }89 function parseGlyfTable(glyf, loca, isGlyphLocationsLong) {90 var itemSize, itemDecode;91 if (isGlyphLocationsLong) {92 itemSize = 4;93 itemDecode = function fontItemDecodeLong(data, offset) {94 return (data[offset] << 24) | (data[offset + 1] << 16) |95 (data[offset + 2] << 8) | data[offset + 3];96 };97 } else {98 itemSize = 2;99 itemDecode = function fontItemDecode(data, offset) {100 return (data[offset] << 9) | (data[offset + 1] << 1);101 };102 }103 var glyphs = [];104 var startOffset = itemDecode(loca, 0);105 for (var j = itemSize; j < loca.length; j += itemSize) {106 var endOffset = itemDecode(loca, j);107 glyphs.push(glyf.subarray(startOffset, endOffset));108 startOffset = endOffset;109 }110 return glyphs;111 }112 function lookupCmap(ranges, unicode) {113 var code = unicode.charCodeAt(0);114 var l = 0, r = ranges.length - 1;115 while (l < r) {116 var c = (l + r + 1) >> 1;117 if (code < ranges[c].start) {118 r = c - 1;119 } else {120 l = c;121 }122 }123 if (ranges[l].start <= code && code <= ranges[l].end) {124 return (ranges[l].idDelta + (ranges[l].ids ?125 ranges[l].ids[code - ranges[l].start] : code)) & 0xFFFF;126 }127 return 0;128 }129 function compileGlyf(code, js, font) {130 function moveTo(x, y) {131 js.push('c.moveTo(' + x + ',' + y + ');');132 }133 function lineTo(x, y) {134 js.push('c.lineTo(' + x + ',' + y + ');');135 }136 function quadraticCurveTo(xa, ya, x, y) {137 js.push('c.quadraticCurveTo(' + xa + ',' + ya + ',' +138 x + ',' + y + ');');139 }140 var i = 0;141 var numberOfContours = ((code[i] << 24) | (code[i + 1] << 16)) >> 16;142 var flags;143 var x = 0, y = 0;144 i += 10;145 if (numberOfContours < 0) {146 // composite glyph147 do {148 flags = (code[i] << 8) | code[i + 1];149 var glyphIndex = (code[i + 2] << 8) | code[i + 3];150 i += 4;151 var arg1, arg2;152 if ((flags & 0x01)) {153 arg1 = ((code[i] << 24) | (code[i + 1] << 16)) >> 16;154 arg2 = ((code[i + 2] << 24) | (code[i + 3] << 16)) >> 16;155 i += 4;156 } else {157 arg1 = code[i++]; arg2 = code[i++];158 }159 if ((flags & 0x02)) {160 x = arg1;161 y = arg2;162 } else {163 x = 0; y = 0; // TODO "they are points" ?164 }165 var scaleX = 1, scaleY = 1, scale01 = 0, scale10 = 0;166 if ((flags & 0x08)) {167 scaleX =168 scaleY = ((code[i] << 24) | (code[i + 1] << 16)) / 1073741824;169 i += 2;170 } else if ((flags & 0x40)) {171 scaleX = ((code[i] << 24) | (code[i + 1] << 16)) / 1073741824;172 scaleY = ((code[i + 2] << 24) | (code[i + 3] << 16)) / 1073741824;173 i += 4;174 } else if ((flags & 0x80)) {175 scaleX = ((code[i] << 24) | (code[i + 1] << 16)) / 1073741824;176 scale01 = ((code[i + 2] << 24) | (code[i + 3] << 16)) / 1073741824;177 scale10 = ((code[i + 4] << 24) | (code[i + 5] << 16)) / 1073741824;178 scaleY = ((code[i + 6] << 24) | (code[i + 7] << 16)) / 1073741824;179 i += 8;180 }181 var subglyph = font.glyphs[glyphIndex];182 if (subglyph) {183 js.push('c.save();');184 js.push('c.transform(' + scaleX + ',' + scale01 + ',' +185 scale10 + ',' + scaleY + ',' + x + ',' + y + ');');186 compileGlyf(subglyph, js, font);187 js.push('c.restore();');188 }189 } while ((flags & 0x20));190 } else {191 // simple glyph192 var endPtsOfContours = [];193 var j, jj;194 for (j = 0; j < numberOfContours; j++) {195 endPtsOfContours.push((code[i] << 8) | code[i + 1]);196 i += 2;197 }198 var instructionLength = (code[i] << 8) | code[i + 1];199 i += 2 + instructionLength; // skipping the instructions200 var numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1;201 var points = [];202 while (points.length < numberOfPoints) {203 flags = code[i++];204 var repeat = 1;205 if ((flags & 0x08)) {206 repeat += code[i++];207 }208 while (repeat-- > 0) {209 points.push({flags: flags});210 }211 }212 for (j = 0; j < numberOfPoints; j++) {213 switch (points[j].flags & 0x12) {214 case 0x00:215 x += ((code[i] << 24) | (code[i + 1] << 16)) >> 16;216 i += 2;217 break;218 case 0x02:219 x -= code[i++];220 break;221 case 0x12:222 x += code[i++];223 break;224 }225 points[j].x = x;226 }227 for (j = 0; j < numberOfPoints; j++) {228 switch (points[j].flags & 0x24) {229 case 0x00:230 y += ((code[i] << 24) | (code[i + 1] << 16)) >> 16;231 i += 2;232 break;233 case 0x04:234 y -= code[i++];235 break;236 case 0x24:237 y += code[i++];238 break;239 }240 points[j].y = y;241 }242 var startPoint = 0;243 for (i = 0; i < numberOfContours; i++) {244 var endPoint = endPtsOfContours[i];245 // contours might have implicit points, which is located in the middle246 // between two neighboring off-curve points247 var contour = points.slice(startPoint, endPoint + 1);248 if ((contour[0].flags & 1)) {249 contour.push(contour[0]); // using start point at the contour end250 } else if ((contour[contour.length - 1].flags & 1)) {251 // first is off-curve point, trying to use one from the end252 contour.unshift(contour[contour.length - 1]);253 } else {254 // start and end are off-curve points, creating implicit one255 var p = {256 flags: 1,257 x: (contour[0].x + contour[contour.length - 1].x) / 2,258 y: (contour[0].y + contour[contour.length - 1].y) / 2259 };260 contour.unshift(p);261 contour.push(p);262 }263 moveTo(contour[0].x, contour[0].y);264 for (j = 1, jj = contour.length; j < jj; j++) {265 if ((contour[j].flags & 1)) {266 lineTo(contour[j].x, contour[j].y);267 } else if ((contour[j + 1].flags & 1)){268 quadraticCurveTo(contour[j].x, contour[j].y,269 contour[j + 1].x, contour[j + 1].y);270 j++;271 } else {272 quadraticCurveTo(contour[j].x, contour[j].y,273 (contour[j].x + contour[j + 1].x) / 2,274 (contour[j].y + contour[j + 1].y) / 2);275 }276 }277 startPoint = endPoint + 1;278 }279 }280 }281 function compileCharString(code, js, font) {282 var stack = [];283 var x = 0, y = 0;284 var stems = 0;285 function moveTo(x, y) {286 js.push('c.moveTo(' + x + ',' + y + ');');287 }288 function lineTo(x, y) {289 js.push('c.lineTo(' + x + ',' + y + ');');290 }291 function bezierCurveTo(x1, y1, x2, y2, x, y) {292 js.push('c.bezierCurveTo(' + x1 + ',' + y1 + ',' + x2 + ',' + y2 + ',' +293 x + ',' + y + ');');294 }295 function parse(code) {296 var i = 0;297 while (i < code.length) {298 var stackClean = false;299 var v = code[i++];300 var xa, xb, ya, yb, y1, y2, y3, n, subrCode;301 switch (v) {302 case 1: // hstem303 stems += stack.length >> 1;304 stackClean = true;305 break;306 case 3: // vstem307 stems += stack.length >> 1;308 stackClean = true;309 break;310 case 4: // vmoveto311 y += stack.pop();312 moveTo(x, y);313 stackClean = true;314 break;315 case 5: // rlineto316 while (stack.length > 0) {317 x += stack.shift();318 y += stack.shift();319 lineTo(x, y);320 }321 break;322 case 6: // hlineto323 while (stack.length > 0) {324 x += stack.shift();325 lineTo(x, y);326 if (stack.length === 0) {327 break;328 }329 y += stack.shift();330 lineTo(x, y);331 }332 break;333 case 7: // vlineto334 while (stack.length > 0) {335 y += stack.shift();336 lineTo(x, y);337 if (stack.length === 0) {338 break;339 }340 x += stack.shift();341 lineTo(x, y);342 }343 break;344 case 8: // rrcurveto345 while (stack.length > 0) {346 xa = x + stack.shift(); ya = y + stack.shift();347 xb = xa + stack.shift(); yb = ya + stack.shift();348 x = xb + stack.shift(); y = yb + stack.shift();349 bezierCurveTo(xa, ya, xb, yb, x, y);350 }351 break;352 case 10: // callsubr353 n = stack.pop() + font.subrsBias;354 subrCode = font.subrs[n];355 if (subrCode) {356 parse(subrCode);357 }358 break;359 case 11: // return360 return;361 case 12:362 v = code[i++];363 switch (v) {364 case 34: // flex365 xa = x + stack.shift();366 xb = xa + stack.shift(); y1 = y + stack.shift();367 x = xb + stack.shift();368 bezierCurveTo(xa, y, xb, y1, x, y1);369 xa = x + stack.shift();370 xb = xa + stack.shift();371 x = xb + stack.shift();372 bezierCurveTo(xa, y1, xb, y, x, y);373 break;374 case 35: // flex375 xa = x + stack.shift(); ya = y + stack.shift();376 xb = xa + stack.shift(); yb = ya + stack.shift();377 x = xb + stack.shift(); y = yb + stack.shift();378 bezierCurveTo(xa, ya, xb, yb, x, y);379 xa = x + stack.shift(); ya = y + stack.shift();380 xb = xa + stack.shift(); yb = ya + stack.shift();381 x = xb + stack.shift(); y = yb + stack.shift();382 bezierCurveTo(xa, ya, xb, yb, x, y);383 stack.pop(); // fd384 break;385 case 36: // hflex1386 xa = x + stack.shift(); y1 = y + stack.shift();387 xb = xa + stack.shift(); y2 = y1 + stack.shift();388 x = xb + stack.shift();389 bezierCurveTo(xa, y1, xb, y2, x, y2);390 xa = x + stack.shift();391 xb = xa + stack.shift(); y3 = y2 + stack.shift();392 x = xb + stack.shift();393 bezierCurveTo(xa, y2, xb, y3, x, y);394 break;395 case 37: // flex1396 var x0 = x, y0 = y;397 xa = x + stack.shift(); ya = y + stack.shift();398 xb = xa + stack.shift(); yb = ya + stack.shift();399 x = xb + stack.shift(); y = yb + stack.shift();400 bezierCurveTo(xa, ya, xb, yb, x, y);401 xa = x + stack.shift(); ya = y + stack.shift();402 xb = xa + stack.shift(); yb = ya + stack.shift();403 x = xb; y = yb;404 if (Math.abs(x - x0) > Math.abs(y - y0)) {405 x += stack.shift();406 } else {407 y += stack.shift();408 }409 bezierCurveTo(xa, ya, xb, yb, x, y);410 break;411 default:412 error('unknown operator: 12 ' + v);413 }414 break;415 case 14: // endchar416 if (stack.length >= 4) {417 var achar = stack.pop();418 var bchar = stack.pop();419 y = stack.pop();420 x = stack.pop();421 js.push('c.save();');422 js.push('c.translate('+ x + ',' + y + ');');423 var gid = lookupCmap(font.cmap, String.fromCharCode(424 font.glyphNameMap[Encodings.StandardEncoding[achar]]));425 compileCharString(font.glyphs[gid], js, font);426 js.push('c.restore();');427 gid = lookupCmap(font.cmap, String.fromCharCode(428 font.glyphNameMap[Encodings.StandardEncoding[bchar]]));429 compileCharString(font.glyphs[gid], js, font);430 }431 return;432 case 18: // hstemhm433 stems += stack.length >> 1;434 stackClean = true;435 break;436 case 19: // hintmask437 stems += stack.length >> 1;438 i += (stems + 7) >> 3;439 stackClean = true;440 break;441 case 20: // cntrmask442 stems += stack.length >> 1;443 i += (stems + 7) >> 3;444 stackClean = true;445 break;446 case 21: // rmoveto447 y += stack.pop();448 x += stack.pop();449 moveTo(x, y);450 stackClean = true;451 break;452 case 22: // hmoveto453 x += stack.pop();454 moveTo(x, y);455 stackClean = true;456 break;457 case 23: // vstemhm458 stems += stack.length >> 1;459 stackClean = true;460 break;461 case 24: // rcurveline462 while (stack.length > 2) {463 xa = x + stack.shift(); ya = y + stack.shift();464 xb = xa + stack.shift(); yb = ya + stack.shift();465 x = xb + stack.shift(); y = yb + stack.shift();466 bezierCurveTo(xa, ya, xb, yb, x, y);467 }468 x += stack.shift();469 y += stack.shift();470 lineTo(x, y);471 break;472 case 25: // rlinecurve473 while (stack.length > 6) {474 x += stack.shift();475 y += stack.shift();476 lineTo(x, y);477 }478 xa = x + stack.shift(); ya = y + stack.shift();479 xb = xa + stack.shift(); yb = ya + stack.shift();480 x = xb + stack.shift(); y = yb + stack.shift();481 bezierCurveTo(xa, ya, xb, yb, x, y);482 break;483 case 26: // vvcurveto484 if (stack.length % 2) {485 x += stack.shift();486 }487 while (stack.length > 0) {488 xa = x; ya = y + stack.shift();489 xb = xa + stack.shift(); yb = ya + stack.shift();490 x = xb; y = yb + stack.shift();491 bezierCurveTo(xa, ya, xb, yb, x, y);492 }493 break;494 case 27: // hhcurveto495 if (stack.length % 2) {496 y += stack.shift();497 }498 while (stack.length > 0) {499 xa = x + stack.shift(); ya = y;500 xb = xa + stack.shift(); yb = ya + stack.shift();501 x = xb + stack.shift(); y = yb;502 bezierCurveTo(xa, ya, xb, yb, x, y);503 }504 break;505 case 28:506 stack.push(((code[i] << 24) | (code[i + 1] << 16)) >> 16);507 i += 2;508 break;509 case 29: // callgsubr510 n = stack.pop() + font.gsubrsBias;511 subrCode = font.gsubrs[n];512 if (subrCode) {513 parse(subrCode);514 }515 break;516 case 30: // vhcurveto517 while (stack.length > 0) {518 xa = x; ya = y + stack.shift();519 xb = xa + stack.shift(); yb = ya + stack.shift();520 x = xb + stack.shift();521 y = yb + (stack.length === 1 ? stack.shift() : 0);522 bezierCurveTo(xa, ya, xb, yb, x, y);523 if (stack.length === 0) {524 break;525 }526 xa = x + stack.shift(); ya = y;527 xb = xa + stack.shift(); yb = ya + stack.shift();528 y = yb + stack.shift();529 x = xb + (stack.length === 1 ? stack.shift() : 0);530 bezierCurveTo(xa, ya, xb, yb, x, y);531 }532 break;533 case 31: // hvcurveto534 while (stack.length > 0) {535 xa = x + stack.shift(); ya = y;536 xb = xa + stack.shift(); yb = ya + stack.shift();537 y = yb + stack.shift();538 x = xb + (stack.length === 1 ? stack.shift() : 0);539 bezierCurveTo(xa, ya, xb, yb, x, y);540 if (stack.length === 0) {541 break;542 }543 xa = x; ya = y + stack.shift();544 xb = xa + stack.shift(); yb = ya + stack.shift();545 x = xb + stack.shift();546 y = yb + (stack.length === 1 ? stack.shift() : 0);547 bezierCurveTo(xa, ya, xb, yb, x, y);548 }549 break;550 default:551 if (v < 32) {552 error('unknown operator: ' + v);553 }554 if (v < 247) {555 stack.push(v - 139);556 } else if (v < 251) {557 stack.push((v - 247) * 256 + code[i++] + 108);558 } else if (v < 255) {559 stack.push(-(v - 251) * 256 - code[i++] - 108);560 } else {561 stack.push(((code[i] << 24) | (code[i + 1] << 16) |562 (code[i + 2] << 8) | code[i + 3]) / 65536);563 i += 4;564 }565 break;566 }567 if (stackClean) {568 stack.length = 0;569 }570 }571 }572 parse(code);573 }574 var noop = '';575 function CompiledFont(fontMatrix) {576 this.compiledGlyphs = {};577 this.fontMatrix = fontMatrix;578 }579 CompiledFont.prototype = {580 getPathJs: function (unicode) {581 var gid = lookupCmap(this.cmap, unicode);582 var fn = this.compiledGlyphs[gid];583 if (!fn) {584 this.compiledGlyphs[gid] = fn = this.compileGlyph(this.glyphs[gid]);585 }586 return fn;587 },588 compileGlyph: function (code) {589 if (!code || code.length === 0 || code[0] === 14) {590 return noop;591 }592 var js = [];593 js.push('c.save();');594 js.push('c.transform(' + this.fontMatrix.join(',') + ');');595 js.push('c.scale(size, -size);');596 this.compileGlyphImpl(code, js);597 js.push('c.restore();');598 return js.join('\n');599 },600 compileGlyphImpl: function () {601 error('Children classes should implement this.');602 },603 hasBuiltPath: function (unicode) {604 var gid = lookupCmap(this.cmap, unicode);605 return gid in this.compiledGlyphs;606 }607 };608 function TrueTypeCompiled(glyphs, cmap, fontMatrix) {609 fontMatrix = fontMatrix || [0.000488, 0, 0, 0.000488, 0, 0];610 CompiledFont.call(this, fontMatrix);611 this.glyphs = glyphs;612 this.cmap = cmap;613 this.compiledGlyphs = [];614 }615 Util.inherit(TrueTypeCompiled, CompiledFont, {616 compileGlyphImpl: function (code, js) {617 compileGlyf(code, js, this);618 }619 });620 function Type2Compiled(cffInfo, cmap, fontMatrix, glyphNameMap) {621 fontMatrix = fontMatrix || [0.001, 0, 0, 0.001, 0, 0];622 CompiledFont.call(this, fontMatrix);623 this.glyphs = cffInfo.glyphs;624 this.gsubrs = cffInfo.gsubrs || [];625 this.subrs = cffInfo.subrs || [];626 this.cmap = cmap;627 this.glyphNameMap = glyphNameMap || GlyphsUnicode;628 this.compiledGlyphs = [];629 this.gsubrsBias = (this.gsubrs.length < 1240 ?630 107 : (this.gsubrs.length < 33900 ? 1131 : 32768));631 this.subrsBias = (this.subrs.length < 1240 ?632 107 : (this.subrs.length < 33900 ? 1131 : 32768));633 }634 Util.inherit(Type2Compiled, CompiledFont, {635 compileGlyphImpl: function (code, js) {636 compileCharString(code, js, this);637 }638 });639 return {640 create: function FontRendererFactory_create(font) {641 var data = new Uint8Array(font.data);642 var cmap, glyf, loca, cff, indexToLocFormat, unitsPerEm;643 var numTables = getUshort(data, 4);644 for (var i = 0, p = 12; i < numTables; i++, p += 16) {645 var tag = bytesToString(data.subarray(p, p + 4));646 var offset = getLong(data, p + 8);647 var length = getLong(data, p + 12);648 switch (tag) {649 case 'cmap':650 cmap = parseCmap(data, offset, offset + length);651 break;652 case 'glyf':653 glyf = data.subarray(offset, offset + length);654 break;655 case 'loca':656 loca = data.subarray(offset, offset + length);657 break;658 case 'head':659 unitsPerEm = getUshort(data, offset + 18);660 indexToLocFormat = getUshort(data, offset + 50);661 break;662 case 'CFF ':663 cff = parseCff(data, offset, offset + length);664 break;665 }666 }667 if (glyf) {668 var fontMatrix = (!unitsPerEm ? font.fontMatrix :669 [1 / unitsPerEm, 0, 0, 1 / unitsPerEm, 0, 0]);670 return new TrueTypeCompiled(671 parseGlyfTable(glyf, loca, indexToLocFormat), cmap, fontMatrix);672 } else {673 return new Type2Compiled(cff, cmap, font.fontMatrix, font.glyphNameMap);674 }675 }676 };677})();
parser.ts
Source:parser.ts
1import { parseCFF } from './tables/cff';2import { parseCmap } from './tables/cmap';3import { parseMATH } from './tables/math';4import { parseHead } from './tables/head';5import { getGlyphMetrics } from './util';6import type { Font, TableRecord, TableDirectory } from './types';7const parseTag = (view: DataView, offset = 0): string => {8 return [9 view.getUint8(offset + 0),10 view.getUint8(offset + 1),11 view.getUint8(offset + 2),12 view.getUint8(offset + 3),13 ]14 .map((x) => String.fromCharCode(x))15 .join('');16};17const parseTableRecords = async (18 blob: Blob,19 offset: number,20 numTables: number,21): Promise<Record<string, TableRecord>> => {22 const RECORD_SIZE = 4 + 4 + 4 + 4;23 const buffer = await blob24 .slice(offset, offset + numTables * RECORD_SIZE)25 .arrayBuffer();26 const view = new DataView(buffer);27 const result: Record<string, TableRecord> = {};28 for (let i = 0; i < numTables; i++) {29 const offset = i * RECORD_SIZE;30 const tag = parseTag(view, offset);31 result[tag] = {32 tableTag: parseTag(view, offset),33 checksum: view.getUint32(offset + 4),34 offset: view.getUint32(offset + 8),35 length: view.getUint32(offset + 12),36 };37 }38 return result;39};40export const parseDirectory = async (blob: Blob): Promise<TableDirectory> => {41 const byteCount = 4 + 8;42 const buffer = await blob.slice(0, byteCount).arrayBuffer();43 const view = new DataView(buffer);44 const numTables = view.getUint16(4);45 const dir: TableDirectory = {46 sfntVersion: parseTag(view), // tag, 4 bytes47 numTables: numTables, // uint1648 searchRange: view.getUint16(6),49 entrySelector: view.getUint16(8),50 rangeShift: view.getUint16(10),51 tableRecords: await parseTableRecords(blob, 12, numTables),52 };53 return dir;54};55export const parse = async (blob: Blob): Promise<Font> => {56 const dir = await parseDirectory(blob);57 const headTableRecord = dir.tableRecords['head'];58 if (!headTableRecord) {59 throw new Error("No TableRecord for 'head' table");60 }61 const headBlob = blob.slice(62 headTableRecord.offset,63 headTableRecord.offset + headTableRecord.length,64 );65 const head = await parseHead(headBlob);66 // TODO: move the blob for each table record into the parseDirector result67 const cmapTableRecord = dir.tableRecords['cmap'];68 if (!cmapTableRecord) {69 throw new Error("No TableRecord for 'cmap' table");70 }71 const cmapBlob = blob.slice(72 cmapTableRecord.offset,73 cmapTableRecord.offset + cmapTableRecord.length,74 );75 const glyphIndexMap = await parseCmap(cmapBlob);76 const mathTableRecord = dir.tableRecords['MATH'];77 if (!mathTableRecord) {78 throw new Error("No TableRecord for 'MATH' table");79 }80 const mathBlob = blob.slice(81 mathTableRecord.offset,82 mathTableRecord.offset + mathTableRecord.length,83 );84 const math = await parseMATH(mathBlob, head.unitsPerEm);85 const cffTableRecord = dir.tableRecords['CFF '];86 if (!cffTableRecord) {87 throw new Error("No TableRecord for 'CFF ' table");88 }89 const cffBlob = blob.slice(90 cffTableRecord.offset,91 cffTableRecord.offset + cffTableRecord.length,92 );93 const cff = await parseCFF(cffBlob);94 const font: Font = {95 cff: {96 name: cff.name,97 topDict: cff.topDict,98 },99 head,100 math,101 getGlyph: cff.getGlyph,102 getGlyphID: (char: string): number => {103 const codePoint = char.codePointAt(0);104 if (!codePoint) {105 throw new Error(`Invalid char: ${char}`);106 }107 const glyphID = glyphIndexMap[codePoint];108 if (!glyphID) {109 throw new Error(`No glyphID in font for given codePoint: ${codePoint}`);110 }111 return glyphID;112 },113 getGlyphMetrics: (gid: number) => {114 const glyph = cff.getGlyph(gid);115 return getGlyphMetrics(glyph);116 },117 };118 return font;...
Using AI Code Generation
1var wptools = require('wptools');2var fs = require('fs');3var request = require('request');4var path = require('path');5var Promise = require('bluebird');6var _ = require('lodash');7var async = require('async');8var request = require('request');9var cheerio = require('cheerio');10var parseCff = require('./parseCff.js');11var parseCff2 = require('./parseCff2.js');
Using AI Code Generation
1const wptools = require('wptools');2const fs = require('fs');3fs.readFile('./test.cff', 'utf8', function (err,data) {4 if (err) {5 return console.log(err);6 }7 console.log(data);8 var cff = wptools.parseCff(data);9 console.log(cff);10});11[MIT](LICENSE)
Using AI Code Generation
1var wptools = require('wptools');2var fs = require('fs');3var parser = require('parse-cff');4var data = fs.readFileSync('test.cff', 'utf8');5console.log(data);6var json = parser.parseCff(data);7console.log(json);
Using AI Code Generation
1var wptools = require('wptools');2var fs = require('fs');3var path = require('path');4var cff = require('cff-converter-js');5var test = new wptools.page('Hans Rosling');6test.parseCff(function(err, cff){7 if(err)8 console.log(err);9 else{10 console.log(cff);11 fs.writeFileSync(path.join(__dirname, 'test.cff'), cff);12 }13});14### page()15var wptools = require('wptools');16var page = new wptools.page('Hans Rosling', {format: 'cff', lang: 'en'});17### parseCff()18var wptools = require('wptools');19var page = new wptools.page('Hans Rosling', {format: 'cff', lang: 'en'});20page.parseCff(function(err, cff){21 if(err)22 console.log(err);23 console.log(cff);24});25### parseJson()26var wptools = require('wptools');27var page = new wptools.page('Hans Rosling', {format: 'cff', lang: 'en'});28page.parseJson(function(err, json){29 if(err)30 console.log(err);31 console.log(json);32});
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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!