Best JavaScript code snippet using wpt
evaluator.js
Source:evaluator.js
...412 },413 loadFont: function PartialEvaluator_loadFont(fontName, font, xref,414 resources) {415 function errorFont() {416 return Promise.resolve(new TranslatedFont('g_font_error',417 new ErrorFont('Font ' + fontName + ' is not available'), font));418 }419 var fontRef;420 if (font) { // Loading by ref.421 assert(isRef(font));422 fontRef = font;423 } else { // Loading by name.424 var fontRes = resources.get('Font');425 if (fontRes) {426 fontRef = fontRes.getRaw(fontName);427 } else {428 warn('fontRes not available');429 return errorFont();430 }431 }432 if (!fontRef) {433 warn('fontRef not available');434 return errorFont();435 }436 if (this.fontCache.has(fontRef)) {437 return this.fontCache.get(fontRef);438 }439 font = xref.fetchIfRef(fontRef);440 if (!isDict(font)) {441 return errorFont();442 }443 // We are holding font.translated references just for fontRef that are not444 // dictionaries (Dict). See explanation below.445 if (font.translated) {446 return font.translated;447 }448 var fontCapability = createPromiseCapability();449 var preEvaluatedFont = this.preEvaluateFont(font, xref);450 var descriptor = preEvaluatedFont.descriptor;451 var fontID = fontRef.num + '_' + fontRef.gen;452 if (isDict(descriptor)) {453 if (!descriptor.fontAliases) {454 descriptor.fontAliases = Object.create(null);455 }456 var fontAliases = descriptor.fontAliases;457 var hash = preEvaluatedFont.hash;458 if (fontAliases[hash]) {459 var aliasFontRef = fontAliases[hash].aliasRef;460 if (aliasFontRef && this.fontCache.has(aliasFontRef)) {461 this.fontCache.putAlias(fontRef, aliasFontRef);462 return this.fontCache.get(fontRef);463 }464 }465 if (!fontAliases[hash]) {466 fontAliases[hash] = {467 fontID: Font.getFontID()468 };469 }470 fontAliases[hash].aliasRef = fontRef;471 fontID = fontAliases[hash].fontID;472 }473 // Workaround for bad PDF generators that don't reference fonts474 // properly, i.e. by not using an object identifier.475 // Check if the fontRef is a Dict (as opposed to a standard object),476 // in which case we don't cache the font and instead reference it by477 // fontName in font.loadedName below.478 var fontRefIsDict = isDict(fontRef);479 if (!fontRefIsDict) {480 this.fontCache.put(fontRef, fontCapability.promise);481 }482 // Keep track of each font we translated so the caller can483 // load them asynchronously before calling display on a page.484 font.loadedName = 'g_font_' + (fontRefIsDict ?485 fontName.replace(/\W/g, '') : fontID);486 font.translated = fontCapability.promise;487 // TODO move promises into translate font488 var translatedPromise;489 try {490 translatedPromise = Promise.resolve(491 this.translateFont(preEvaluatedFont, xref));492 } catch (e) {493 translatedPromise = Promise.reject(e);494 }495 translatedPromise.then(function (translatedFont) {496 if (translatedFont.fontType !== undefined) {497 var xrefFontStats = xref.stats.fontTypes;498 xrefFontStats[translatedFont.fontType] = true;499 }500 fontCapability.resolve(new TranslatedFont(font.loadedName,501 translatedFont, font));502 }, function (reason) {503 // TODO fontCapability.reject?504 UnsupportedManager.notify(UNSUPPORTED_FEATURES.font);505 try {506 // error, but it's still nice to have font type reported507 var descriptor = preEvaluatedFont.descriptor;508 var fontFile3 = descriptor && descriptor.get('FontFile3');509 var subtype = fontFile3 && fontFile3.get('Subtype');510 var fontType = getFontType(preEvaluatedFont.type,511 subtype && subtype.name);512 var xrefFontStats = xref.stats.fontTypes;513 xrefFontStats[fontType] = true;514 } catch (ex) { }515 fontCapability.resolve(new TranslatedFont(font.loadedName,516 new ErrorFont(reason instanceof Error ? reason.message : reason),517 font));518 });519 return fontCapability.promise;520 },521 buildPath: function PartialEvaluator_buildPath(operatorList, fn, args) {522 var lastIndex = operatorList.length - 1;523 if (!args) {524 args = [];525 }526 if (lastIndex < 0 ||527 operatorList.fnArray[lastIndex] !== OPS.constructPath) {528 operatorList.addOp(OPS.constructPath, [[fn], args]);529 } else {530 var opArgs = operatorList.argsArray[lastIndex];531 opArgs[0].push(fn);532 Array.prototype.push.apply(opArgs[1], args);533 }534 },535 handleColorN: function PartialEvaluator_handleColorN(operatorList, fn, args,536 cs, patterns, resources, xref) {537 // compile tiling patterns538 var patternName = args[args.length - 1];539 // SCN/scn applies patterns along with normal colors540 var pattern;541 if (isName(patternName) &&542 (pattern = patterns.get(patternName.name))) {543 var dict = (isStream(pattern) ? pattern.dict : pattern);544 var typeNum = dict.get('PatternType');545 if (typeNum === TILING_PATTERN) {546 var color = cs.base ? cs.base.getRgb(args, 0) : null;547 return this.handleTilingType(fn, color, resources, pattern,548 dict, operatorList);549 } else if (typeNum === SHADING_PATTERN) {550 var shading = dict.get('Shading');551 var matrix = dict.get('Matrix');552 pattern = Pattern.parseShading(shading, matrix, xref, resources);553 operatorList.addOp(fn, pattern.getIR());554 return Promise.resolve();555 } else {556 return Promise.reject('Unknown PatternType: ' + typeNum);557 }558 }559 // TODO shall we fail here?560 operatorList.addOp(fn, args);561 return Promise.resolve();562 },563 getOperatorList: function PartialEvaluator_getOperatorList(stream,564 resources,565 operatorList,566 initialState) {567 var self = this;568 var xref = this.xref;569 var imageCache = {};570 assert(operatorList);571 resources = (resources || Dict.empty);572 var xobjs = (resources.get('XObject') || Dict.empty);573 var patterns = (resources.get('Pattern') || Dict.empty);574 var stateManager = new StateManager(initialState || new EvalState());575 var preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager);576 var timeSlotManager = new TimeSlotManager();577 return new Promise(function next(resolve, reject) {578 timeSlotManager.reset();579 var stop, operation = {}, i, ii, cs;580 while (!(stop = timeSlotManager.check())) {581 // The arguments parsed by read() are used beyond this loop, so we582 // cannot reuse the same array on each iteration. Therefore we pass583 // in |null| as the initial value (see the comment on584 // EvaluatorPreprocessor_read() for why).585 operation.args = null;586 if (!(preprocessor.read(operation))) {587 break;588 }589 var args = operation.args;590 var fn = operation.fn;591 switch (fn | 0) {592 case OPS.paintXObject:593 if (args[0].code) {594 break;595 }596 // eagerly compile XForm objects597 var name = args[0].name;598 if (imageCache[name] !== undefined) {599 operatorList.addOp(imageCache[name].fn, imageCache[name].args);600 args = null;601 continue;602 }603 var xobj = xobjs.get(name);604 if (xobj) {605 assert(isStream(xobj), 'XObject should be a stream');606 var type = xobj.dict.get('Subtype');607 assert(isName(type),608 'XObject should have a Name subtype');609 if (type.name === 'Form') {610 stateManager.save();611 return self.buildFormXObject(resources, xobj, null,612 operatorList,613 stateManager.state.clone()).614 then(function () {615 stateManager.restore();616 next(resolve, reject);617 }, reject);618 } else if (type.name === 'Image') {619 self.buildPaintImageXObject(resources, xobj, false,620 operatorList, name, imageCache);621 args = null;622 continue;623 } else if (type.name === 'PS') {624 // PostScript XObjects are unused when viewing documents.625 // See section 4.7.1 of Adobe's PDF reference.626 info('Ignored XObject subtype PS');627 continue;628 } else {629 error('Unhandled XObject subtype ' + type.name);630 }631 }632 break;633 case OPS.setFont:634 var fontSize = args[1];635 // eagerly collect all fonts636 return self.handleSetFont(resources, args, null,637 operatorList, stateManager.state).638 then(function (loadedName) {639 operatorList.addDependency(loadedName);640 operatorList.addOp(OPS.setFont, [loadedName, fontSize]);641 next(resolve, reject);642 }, reject);643 case OPS.endInlineImage:644 var cacheKey = args[0].cacheKey;645 if (cacheKey) {646 var cacheEntry = imageCache[cacheKey];647 if (cacheEntry !== undefined) {648 operatorList.addOp(cacheEntry.fn, cacheEntry.args);649 args = null;650 continue;651 }652 }653 self.buildPaintImageXObject(resources, args[0], true,654 operatorList, cacheKey, imageCache);655 args = null;656 continue;657 case OPS.showText:658 args[0] = self.handleText(args[0], stateManager.state);659 break;660 case OPS.showSpacedText:661 var arr = args[0];662 var combinedGlyphs = [];663 var arrLength = arr.length;664 for (i = 0; i < arrLength; ++i) {665 var arrItem = arr[i];666 if (isString(arrItem)) {667 Array.prototype.push.apply(combinedGlyphs,668 self.handleText(arrItem, stateManager.state));669 } else if (isNum(arrItem)) {670 combinedGlyphs.push(arrItem);671 }672 }673 args[0] = combinedGlyphs;674 fn = OPS.showText;675 break;676 case OPS.nextLineShowText:677 operatorList.addOp(OPS.nextLine);678 args[0] = self.handleText(args[0], stateManager.state);679 fn = OPS.showText;680 break;681 case OPS.nextLineSetSpacingShowText:682 operatorList.addOp(OPS.nextLine);683 operatorList.addOp(OPS.setWordSpacing, [args.shift()]);684 operatorList.addOp(OPS.setCharSpacing, [args.shift()]);685 args[0] = self.handleText(args[0], stateManager.state);686 fn = OPS.showText;687 break;688 case OPS.setTextRenderingMode:689 stateManager.state.textRenderingMode = args[0];690 break;691 case OPS.setFillColorSpace:692 stateManager.state.fillColorSpace =693 ColorSpace.parse(args[0], xref, resources);694 continue;695 case OPS.setStrokeColorSpace:696 stateManager.state.strokeColorSpace =697 ColorSpace.parse(args[0], xref, resources);698 continue;699 case OPS.setFillColor:700 cs = stateManager.state.fillColorSpace;701 args = cs.getRgb(args, 0);702 fn = OPS.setFillRGBColor;703 break;704 case OPS.setStrokeColor:705 cs = stateManager.state.strokeColorSpace;706 args = cs.getRgb(args, 0);707 fn = OPS.setStrokeRGBColor;708 break;709 case OPS.setFillGray:710 stateManager.state.fillColorSpace = ColorSpace.singletons.gray;711 args = ColorSpace.singletons.gray.getRgb(args, 0);712 fn = OPS.setFillRGBColor;713 break;714 case OPS.setStrokeGray:715 stateManager.state.strokeColorSpace = ColorSpace.singletons.gray;716 args = ColorSpace.singletons.gray.getRgb(args, 0);717 fn = OPS.setStrokeRGBColor;718 break;719 case OPS.setFillCMYKColor:720 stateManager.state.fillColorSpace = ColorSpace.singletons.cmyk;721 args = ColorSpace.singletons.cmyk.getRgb(args, 0);722 fn = OPS.setFillRGBColor;723 break;724 case OPS.setStrokeCMYKColor:725 stateManager.state.strokeColorSpace = ColorSpace.singletons.cmyk;726 args = ColorSpace.singletons.cmyk.getRgb(args, 0);727 fn = OPS.setStrokeRGBColor;728 break;729 case OPS.setFillRGBColor:730 stateManager.state.fillColorSpace = ColorSpace.singletons.rgb;731 args = ColorSpace.singletons.rgb.getRgb(args, 0);732 break;733 case OPS.setStrokeRGBColor:734 stateManager.state.strokeColorSpace = ColorSpace.singletons.rgb;735 args = ColorSpace.singletons.rgb.getRgb(args, 0);736 break;737 case OPS.setFillColorN:738 cs = stateManager.state.fillColorSpace;739 if (cs.name === 'Pattern') {740 return self.handleColorN(operatorList, OPS.setFillColorN,741 args, cs, patterns, resources, xref).then(function() {742 next(resolve, reject);743 }, reject);744 }745 args = cs.getRgb(args, 0);746 fn = OPS.setFillRGBColor;747 break;748 case OPS.setStrokeColorN:749 cs = stateManager.state.strokeColorSpace;750 if (cs.name === 'Pattern') {751 return self.handleColorN(operatorList, OPS.setStrokeColorN,752 args, cs, patterns, resources, xref).then(function() {753 next(resolve, reject);754 }, reject);755 }756 args = cs.getRgb(args, 0);757 fn = OPS.setStrokeRGBColor;758 break;759 case OPS.shadingFill:760 var shadingRes = resources.get('Shading');761 if (!shadingRes) {762 error('No shading resource found');763 }764 var shading = shadingRes.get(args[0].name);765 if (!shading) {766 error('No shading object found');767 }768 var shadingFill = Pattern.parseShading(shading, null, xref,769 resources);770 var patternIR = shadingFill.getIR();771 args = [patternIR];772 fn = OPS.shadingFill;773 break;774 case OPS.setGState:775 var dictName = args[0];776 var extGState = resources.get('ExtGState');777 if (!isDict(extGState) || !extGState.has(dictName.name)) {778 break;779 }780 var gState = extGState.get(dictName.name);781 return self.setGState(resources, gState, operatorList, xref,782 stateManager).then(function() {783 next(resolve, reject);784 }, reject);785 case OPS.moveTo:786 case OPS.lineTo:787 case OPS.curveTo:788 case OPS.curveTo2:789 case OPS.curveTo3:790 case OPS.closePath:791 self.buildPath(operatorList, fn, args);792 continue;793 case OPS.rectangle:794 self.buildPath(operatorList, fn, args);795 continue;796 }797 operatorList.addOp(fn, args);798 }799 if (stop) {800 deferred.then(function () {801 next(resolve, reject);802 });803 return;804 }805 // Some PDFs don't close all restores inside object/form.806 // Closing those for them.807 for (i = 0, ii = preprocessor.savedStatesDepth; i < ii; i++) {808 operatorList.addOp(OPS.restore, []);809 }810 resolve();811 });812 },813 getTextContent: function PartialEvaluator_getTextContent(stream, resources,814 stateManager) {815 stateManager = (stateManager || new StateManager(new TextState()));816 var textContent = {817 items: [],818 styles: Object.create(null)819 };820 var bidiTexts = textContent.items;821 var SPACE_FACTOR = 0.3;822 var MULTI_SPACE_FACTOR = 1.5;823 var self = this;824 var xref = this.xref;825 resources = (xref.fetchIfRef(resources) || Dict.empty);826 // The xobj is parsed iff it's needed, e.g. if there is a `DO` cmd.827 var xobjs = null;828 var xobjsCache = {};829 var preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager);830 var textState;831 function newTextChunk() {832 var font = textState.font;833 if (!(font.loadedName in textContent.styles)) {834 textContent.styles[font.loadedName] = {835 fontFamily: font.fallbackName,836 ascent: font.ascent,837 descent: font.descent,838 vertical: font.vertical839 };840 }841 return {842 // |str| is initially an array which we push individual chars to, and843 // then runBidi() overwrites it with the final string.844 str: [],845 dir: null,846 width: 0,847 height: 0,848 transform: null,849 fontName: font.loadedName850 };851 }852 function runBidi(textChunk) {853 var str = textChunk.str.join('');854 var bidiResult = PDFJS.bidi(str, -1, textState.font.vertical);855 textChunk.str = bidiResult.str;856 textChunk.dir = bidiResult.dir;857 return textChunk;858 }859 function handleSetFont(fontName, fontRef) {860 return self.loadFont(fontName, fontRef, xref, resources).861 then(function (translated) {862 textState.font = translated.font;863 textState.fontMatrix = translated.font.fontMatrix ||864 FONT_IDENTITY_MATRIX;865 });866 }867 function buildTextGeometry(chars, textChunk) {868 var font = textState.font;869 textChunk = textChunk || newTextChunk();870 if (!textChunk.transform) {871 // 9.4.4 Text Space Details872 var tsm = [textState.fontSize * textState.textHScale, 0,873 0, textState.fontSize,874 0, textState.textRise];875 var trm = textChunk.transform = Util.transform(textState.ctm,876 Util.transform(textState.textMatrix, tsm));877 if (!font.vertical) {878 textChunk.height = Math.sqrt(trm[2] * trm[2] + trm[3] * trm[3]);879 } else {880 textChunk.width = Math.sqrt(trm[0] * trm[0] + trm[1] * trm[1]);881 }882 }883 var width = 0;884 var height = 0;885 var glyphs = font.charsToGlyphs(chars);886 var defaultVMetrics = font.defaultVMetrics;887 for (var i = 0; i < glyphs.length; i++) {888 var glyph = glyphs[i];889 if (!glyph) { // Previous glyph was a space.890 width += textState.wordSpacing * textState.textHScale;891 continue;892 }893 var vMetricX = null;894 var vMetricY = null;895 var glyphWidth = null;896 if (font.vertical) {897 if (glyph.vmetric) {898 glyphWidth = glyph.vmetric[0];899 vMetricX = glyph.vmetric[1];900 vMetricY = glyph.vmetric[2];901 } else {902 glyphWidth = glyph.width;903 vMetricX = glyph.width * 0.5;904 vMetricY = defaultVMetrics[2];905 }906 } else {907 glyphWidth = glyph.width;908 }909 var glyphUnicode = glyph.unicode;910 if (NormalizedUnicodes[glyphUnicode] !== undefined) {911 glyphUnicode = NormalizedUnicodes[glyphUnicode];912 }913 glyphUnicode = reverseIfRtl(glyphUnicode);914 // The following will calculate the x and y of the individual glyphs.915 // if (font.vertical) {916 // tsm[4] -= vMetricX * Math.abs(textState.fontSize) *917 // textState.fontMatrix[0];918 // tsm[5] -= vMetricY * textState.fontSize *919 // textState.fontMatrix[0];920 // }921 // var trm = Util.transform(textState.textMatrix, tsm);922 // var pt = Util.applyTransform([trm[4], trm[5]], textState.ctm);923 // var x = pt[0];924 // var y = pt[1];925 var tx = 0;926 var ty = 0;927 if (!font.vertical) {928 var w0 = glyphWidth * textState.fontMatrix[0];929 tx = (w0 * textState.fontSize + textState.charSpacing) *930 textState.textHScale;931 width += tx;932 } else {933 var w1 = glyphWidth * textState.fontMatrix[0];934 ty = w1 * textState.fontSize + textState.charSpacing;935 height += ty;936 }937 textState.translateTextMatrix(tx, ty);938 textChunk.str.push(glyphUnicode);939 }940 var a = textState.textLineMatrix[0];941 var b = textState.textLineMatrix[1];942 var scaleLineX = Math.sqrt(a * a + b * b);943 a = textState.ctm[0];944 b = textState.ctm[1];945 var scaleCtmX = Math.sqrt(a * a + b * b);946 if (!font.vertical) {947 textChunk.width += width * scaleCtmX * scaleLineX;948 } else {949 textChunk.height += Math.abs(height * scaleCtmX * scaleLineX);950 }951 return textChunk;952 }953 var timeSlotManager = new TimeSlotManager();954 return new Promise(function next(resolve, reject) {955 timeSlotManager.reset();956 var stop, operation = {}, args = [];957 while (!(stop = timeSlotManager.check())) {958 // The arguments parsed by read() are not used beyond this loop, so959 // we can reuse the same array on every iteration, thus avoiding960 // unnecessary allocations.961 args.length = 0;962 operation.args = args;963 if (!(preprocessor.read(operation))) {964 break;965 }966 textState = stateManager.state;967 var fn = operation.fn;968 args = operation.args;969 switch (fn | 0) {970 case OPS.setFont:971 textState.fontSize = args[1];972 return handleSetFont(args[0].name).then(function() {973 next(resolve, reject);974 }, reject);975 case OPS.setTextRise:976 textState.textRise = args[0];977 break;978 case OPS.setHScale:979 textState.textHScale = args[0] / 100;980 break;981 case OPS.setLeading:982 textState.leading = args[0];983 break;984 case OPS.moveText:985 textState.translateTextLineMatrix(args[0], args[1]);986 textState.textMatrix = textState.textLineMatrix.slice();987 break;988 case OPS.setLeadingMoveText:989 textState.leading = -args[1];990 textState.translateTextLineMatrix(args[0], args[1]);991 textState.textMatrix = textState.textLineMatrix.slice();992 break;993 case OPS.nextLine:994 textState.carriageReturn();995 break;996 case OPS.setTextMatrix:997 textState.setTextMatrix(args[0], args[1], args[2], args[3],998 args[4], args[5]);999 textState.setTextLineMatrix(args[0], args[1], args[2], args[3],1000 args[4], args[5]);1001 break;1002 case OPS.setCharSpacing:1003 textState.charSpacing = args[0];1004 break;1005 case OPS.setWordSpacing:1006 textState.wordSpacing = args[0];1007 break;1008 case OPS.beginText:1009 textState.textMatrix = IDENTITY_MATRIX.slice();1010 textState.textLineMatrix = IDENTITY_MATRIX.slice();1011 break;1012 case OPS.showSpacedText:1013 var items = args[0];1014 var textChunk = newTextChunk();1015 var offset;1016 for (var j = 0, jj = items.length; j < jj; j++) {1017 if (typeof items[j] === 'string') {1018 buildTextGeometry(items[j], textChunk);1019 } else {1020 var val = items[j] / 1000;1021 if (!textState.font.vertical) {1022 offset = -val * textState.fontSize * textState.textHScale *1023 textState.textMatrix[0];1024 textState.translateTextMatrix(offset, 0);1025 textChunk.width += offset;1026 } else {1027 offset = -val * textState.fontSize *1028 textState.textMatrix[3];1029 textState.translateTextMatrix(0, offset);1030 textChunk.height += offset;1031 }1032 if (items[j] < 0 && textState.font.spaceWidth > 0) {1033 var fakeSpaces = -items[j] / textState.font.spaceWidth;1034 if (fakeSpaces > MULTI_SPACE_FACTOR) {1035 fakeSpaces = Math.round(fakeSpaces);1036 while (fakeSpaces--) {1037 textChunk.str.push(' ');1038 }1039 } else if (fakeSpaces > SPACE_FACTOR) {1040 textChunk.str.push(' ');1041 }1042 }1043 }1044 }1045 bidiTexts.push(runBidi(textChunk));1046 break;1047 case OPS.showText:1048 bidiTexts.push(runBidi(buildTextGeometry(args[0])));1049 break;1050 case OPS.nextLineShowText:1051 textState.carriageReturn();1052 bidiTexts.push(runBidi(buildTextGeometry(args[0])));1053 break;1054 case OPS.nextLineSetSpacingShowText:1055 textState.wordSpacing = args[0];1056 textState.charSpacing = args[1];1057 textState.carriageReturn();1058 bidiTexts.push(runBidi(buildTextGeometry(args[2])));1059 break;1060 case OPS.paintXObject:1061 if (args[0].code) {1062 break;1063 }1064 if (!xobjs) {1065 xobjs = (resources.get('XObject') || Dict.empty);1066 }1067 var name = args[0].name;1068 if (xobjsCache.key === name) {1069 if (xobjsCache.texts) {1070 Util.appendToArray(bidiTexts, xobjsCache.texts.items);1071 Util.extendObj(textContent.styles, xobjsCache.texts.styles);1072 }1073 break;1074 }1075 var xobj = xobjs.get(name);1076 if (!xobj) {1077 break;1078 }1079 assert(isStream(xobj), 'XObject should be a stream');1080 var type = xobj.dict.get('Subtype');1081 assert(isName(type),1082 'XObject should have a Name subtype');1083 if ('Form' !== type.name) {1084 xobjsCache.key = name;1085 xobjsCache.texts = null;1086 break;1087 }1088 stateManager.save();1089 var matrix = xobj.dict.get('Matrix');1090 if (isArray(matrix) && matrix.length === 6) {1091 stateManager.transform(matrix);1092 }1093 return self.getTextContent(xobj,1094 xobj.dict.get('Resources') || resources, stateManager).1095 then(function (formTextContent) {1096 Util.appendToArray(bidiTexts, formTextContent.items);1097 Util.extendObj(textContent.styles, formTextContent.styles);1098 stateManager.restore();1099 xobjsCache.key = name;1100 xobjsCache.texts = formTextContent;1101 next(resolve, reject);1102 }, reject);1103 case OPS.setGState:1104 var dictName = args[0];1105 var extGState = resources.get('ExtGState');1106 if (!isDict(extGState) || !extGState.has(dictName.name)) {1107 break;1108 }1109 var gsStateMap = extGState.get(dictName.name);1110 var gsStateFont = null;1111 for (var key in gsStateMap) {1112 if (key === 'Font') {1113 assert(!gsStateFont);1114 gsStateFont = gsStateMap[key];1115 }1116 }1117 if (gsStateFont) {1118 textState.fontSize = gsStateFont[1];1119 return handleSetFont(gsStateFont[0]).then(function() {1120 next(resolve, reject);1121 }, reject);1122 }1123 break;1124 } // switch1125 } // while1126 if (stop) {1127 deferred.then(function () {1128 next(resolve, reject);1129 });1130 return;1131 }1132 resolve(textContent);1133 });1134 },1135 extractDataStructures: function1136 partialEvaluatorExtractDataStructures(dict, baseDict,1137 xref, properties) {1138 // 9.10.21139 var toUnicode = (dict.get('ToUnicode') || baseDict.get('ToUnicode'));1140 if (toUnicode) {1141 properties.toUnicode = this.readToUnicode(toUnicode);1142 }1143 if (properties.composite) {1144 // CIDSystemInfo helps to match CID to glyphs1145 var cidSystemInfo = dict.get('CIDSystemInfo');1146 if (isDict(cidSystemInfo)) {1147 properties.cidSystemInfo = {1148 registry: cidSystemInfo.get('Registry'),1149 ordering: cidSystemInfo.get('Ordering'),1150 supplement: cidSystemInfo.get('Supplement')1151 };1152 }1153 var cidToGidMap = dict.get('CIDToGIDMap');1154 if (isStream(cidToGidMap)) {1155 properties.cidToGidMap = this.readCidToGidMap(cidToGidMap);1156 }1157 }1158 // Based on 9.6.6 of the spec the encoding can come from multiple places1159 // and depends on the font type. The base encoding and differences are1160 // read here, but the encoding that is actually used is chosen during1161 // glyph mapping in the font.1162 // TODO: Loading the built in encoding in the font would allow the1163 // differences to be merged in here not require us to hold on to it.1164 var differences = [];1165 var baseEncodingName = null;1166 var encoding;1167 if (dict.has('Encoding')) {1168 encoding = dict.get('Encoding');1169 if (isDict(encoding)) {1170 baseEncodingName = encoding.get('BaseEncoding');1171 baseEncodingName = (isName(baseEncodingName) ?1172 baseEncodingName.name : null);1173 // Load the differences between the base and original1174 if (encoding.has('Differences')) {1175 var diffEncoding = encoding.get('Differences');1176 var index = 0;1177 for (var j = 0, jj = diffEncoding.length; j < jj; j++) {1178 var data = diffEncoding[j];1179 if (isNum(data)) {1180 index = data;1181 } else {1182 differences[index++] = data.name;1183 }1184 }1185 }1186 } else if (isName(encoding)) {1187 baseEncodingName = encoding.name;1188 } else {1189 error('Encoding is not a Name nor a Dict');1190 }1191 // According to table 114 if the encoding is a named encoding it must be1192 // one of these predefined encodings.1193 if ((baseEncodingName !== 'MacRomanEncoding' &&1194 baseEncodingName !== 'MacExpertEncoding' &&1195 baseEncodingName !== 'WinAnsiEncoding')) {1196 baseEncodingName = null;1197 }1198 }1199 if (baseEncodingName) {1200 properties.defaultEncoding = Encodings[baseEncodingName].slice();1201 } else {1202 encoding = (properties.type === 'TrueType' ?1203 Encodings.WinAnsiEncoding : Encodings.StandardEncoding);1204 // The Symbolic attribute can be misused for regular fonts1205 // Heuristic: we have to check if the font is a standard one also1206 if (!!(properties.flags & FontFlags.Symbolic)) {1207 encoding = Encodings.MacRomanEncoding;1208 if (!properties.file) {1209 if (/Symbol/i.test(properties.name)) {1210 encoding = Encodings.SymbolSetEncoding;1211 } else if (/Dingbats/i.test(properties.name)) {1212 encoding = Encodings.ZapfDingbatsEncoding;1213 }1214 }1215 }1216 properties.defaultEncoding = encoding;1217 }1218 properties.differences = differences;1219 properties.baseEncodingName = baseEncodingName;1220 properties.dict = dict;1221 },1222 readToUnicode: function PartialEvaluator_readToUnicode(toUnicode) {1223 var cmap, cmapObj = toUnicode;1224 if (isName(cmapObj)) {1225 cmap = CMapFactory.create(cmapObj,1226 { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null);1227 if (cmap instanceof IdentityCMap) {1228 return new IdentityToUnicodeMap(0, 0xFFFF);1229 }1230 return new ToUnicodeMap(cmap.getMap());1231 } else if (isStream(cmapObj)) {1232 cmap = CMapFactory.create(cmapObj,1233 { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null);1234 if (cmap instanceof IdentityCMap) {1235 return new IdentityToUnicodeMap(0, 0xFFFF);1236 }1237 cmap = cmap.getMap();1238 // Convert UTF-16BE1239 // NOTE: cmap can be a sparse array, so use forEach instead of for(;;)1240 // to iterate over all keys.1241 cmap.forEach(function(token, i) {1242 var str = [];1243 for (var k = 0; k < token.length; k += 2) {1244 var w1 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1);1245 if ((w1 & 0xF800) !== 0xD800) { // w1 < 0xD800 || w1 > 0xDFFF1246 str.push(w1);1247 continue;1248 }1249 k += 2;1250 var w2 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1);1251 str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000);1252 }1253 cmap[i] = String.fromCharCode.apply(String, str);1254 });1255 return new ToUnicodeMap(cmap);1256 }1257 return null;1258 },1259 readCidToGidMap: function PartialEvaluator_readCidToGidMap(cidToGidStream) {1260 // Extract the encoding from the CIDToGIDMap1261 var glyphsData = cidToGidStream.getBytes();1262 // Set encoding 0 to later verify the font has an encoding1263 var result = [];1264 for (var j = 0, jj = glyphsData.length; j < jj; j++) {1265 var glyphID = (glyphsData[j++] << 8) | glyphsData[j];1266 if (glyphID === 0) {1267 continue;1268 }1269 var code = j >> 1;1270 result[code] = glyphID;1271 }1272 return result;1273 },1274 extractWidths: function PartialEvaluator_extractWidths(dict, xref,1275 descriptor,1276 properties) {1277 var glyphsWidths = [];1278 var defaultWidth = 0;1279 var glyphsVMetrics = [];1280 var defaultVMetrics;1281 var i, ii, j, jj, start, code, widths;1282 if (properties.composite) {1283 defaultWidth = dict.get('DW') || 1000;1284 widths = dict.get('W');1285 if (widths) {1286 for (i = 0, ii = widths.length; i < ii; i++) {1287 start = widths[i++];1288 code = xref.fetchIfRef(widths[i]);1289 if (isArray(code)) {1290 for (j = 0, jj = code.length; j < jj; j++) {1291 glyphsWidths[start++] = code[j];1292 }1293 } else {1294 var width = widths[++i];1295 for (j = start; j <= code; j++) {1296 glyphsWidths[j] = width;1297 }1298 }1299 }1300 }1301 if (properties.vertical) {1302 var vmetrics = (dict.get('DW2') || [880, -1000]);1303 defaultVMetrics = [vmetrics[1], defaultWidth * 0.5, vmetrics[0]];1304 vmetrics = dict.get('W2');1305 if (vmetrics) {1306 for (i = 0, ii = vmetrics.length; i < ii; i++) {1307 start = vmetrics[i++];1308 code = xref.fetchIfRef(vmetrics[i]);1309 if (isArray(code)) {1310 for (j = 0, jj = code.length; j < jj; j++) {1311 glyphsVMetrics[start++] = [code[j++], code[j++], code[j]];1312 }1313 } else {1314 var vmetric = [vmetrics[++i], vmetrics[++i], vmetrics[++i]];1315 for (j = start; j <= code; j++) {1316 glyphsVMetrics[j] = vmetric;1317 }1318 }1319 }1320 }1321 }1322 } else {1323 var firstChar = properties.firstChar;1324 widths = dict.get('Widths');1325 if (widths) {1326 j = firstChar;1327 for (i = 0, ii = widths.length; i < ii; i++) {1328 glyphsWidths[j++] = widths[i];1329 }1330 defaultWidth = (parseFloat(descriptor.get('MissingWidth')) || 0);1331 } else {1332 // Trying get the BaseFont metrics (see comment above).1333 var baseFontName = dict.get('BaseFont');1334 if (isName(baseFontName)) {1335 var metrics = this.getBaseFontMetrics(baseFontName.name);1336 glyphsWidths = this.buildCharCodeToWidth(metrics.widths,1337 properties);1338 defaultWidth = metrics.defaultWidth;1339 }1340 }1341 }1342 // Heuristic: detection of monospace font by checking all non-zero widths1343 var isMonospace = true;1344 var firstWidth = defaultWidth;1345 for (var glyph in glyphsWidths) {1346 var glyphWidth = glyphsWidths[glyph];1347 if (!glyphWidth) {1348 continue;1349 }1350 if (!firstWidth) {1351 firstWidth = glyphWidth;1352 continue;1353 }1354 if (firstWidth !== glyphWidth) {1355 isMonospace = false;1356 break;1357 }1358 }1359 if (isMonospace) {1360 properties.flags |= FontFlags.FixedPitch;1361 }1362 properties.defaultWidth = defaultWidth;1363 properties.widths = glyphsWidths;1364 properties.defaultVMetrics = defaultVMetrics;1365 properties.vmetrics = glyphsVMetrics;1366 },1367 isSerifFont: function PartialEvaluator_isSerifFont(baseFontName) {1368 // Simulating descriptor flags attribute1369 var fontNameWoStyle = baseFontName.split('-')[0];1370 return (fontNameWoStyle in serifFonts) ||1371 (fontNameWoStyle.search(/serif/gi) !== -1);1372 },1373 getBaseFontMetrics: function PartialEvaluator_getBaseFontMetrics(name) {1374 var defaultWidth = 0;1375 var widths = [];1376 var monospace = false;1377 var lookupName = (stdFontMap[name] || name);1378 if (!(lookupName in Metrics)) {1379 // Use default fonts for looking up font metrics if the passed1380 // font is not a base font1381 if (this.isSerifFont(name)) {1382 lookupName = 'Times-Roman';1383 } else {1384 lookupName = 'Helvetica';1385 }1386 }1387 var glyphWidths = Metrics[lookupName];1388 if (isNum(glyphWidths)) {1389 defaultWidth = glyphWidths;1390 monospace = true;1391 } else {1392 widths = glyphWidths;1393 }1394 return {1395 defaultWidth: defaultWidth,1396 monospace: monospace,1397 widths: widths1398 };1399 },1400 buildCharCodeToWidth:1401 function PartialEvaluator_bulildCharCodeToWidth(widthsByGlyphName,1402 properties) {1403 var widths = Object.create(null);1404 var differences = properties.differences;1405 var encoding = properties.defaultEncoding;1406 for (var charCode = 0; charCode < 256; charCode++) {1407 if (charCode in differences &&1408 widthsByGlyphName[differences[charCode]]) {1409 widths[charCode] = widthsByGlyphName[differences[charCode]];1410 continue;1411 }1412 if (charCode in encoding && widthsByGlyphName[encoding[charCode]]) {1413 widths[charCode] = widthsByGlyphName[encoding[charCode]];1414 continue;1415 }1416 }1417 return widths;1418 },1419 preEvaluateFont: function PartialEvaluator_preEvaluateFont(dict, xref) {1420 var baseDict = dict;1421 var type = dict.get('Subtype');1422 assert(isName(type), 'invalid font Subtype');1423 var composite = false;1424 var uint8array;1425 if (type.name === 'Type0') {1426 // If font is a composite1427 // - get the descendant font1428 // - set the type according to the descendant font1429 // - get the FontDescriptor from the descendant font1430 var df = dict.get('DescendantFonts');1431 if (!df) {1432 error('Descendant fonts are not specified');1433 }1434 dict = (isArray(df) ? xref.fetchIfRef(df[0]) : df);1435 type = dict.get('Subtype');1436 assert(isName(type), 'invalid font Subtype');1437 composite = true;1438 }1439 var descriptor = dict.get('FontDescriptor');1440 if (descriptor) {1441 var hash = new MurmurHash3_64();1442 var encoding = baseDict.getRaw('Encoding');1443 if (isName(encoding)) {1444 hash.update(encoding.name);1445 } else if (isRef(encoding)) {1446 hash.update(encoding.num + '_' + encoding.gen);1447 } else if (isDict(encoding)) {1448 var keys = encoding.getKeys();1449 for (var i = 0, ii = keys.length; i < ii; i++) {1450 var entry = encoding.getRaw(keys[i]);1451 if (isName(entry)) {1452 hash.update(entry.name);1453 } else if (isRef(entry)) {1454 hash.update(entry.num + '_' + entry.gen);1455 } else if (isArray(entry)) { // 'Differences' entry.1456 // Ideally we should check the contents of the array, but to avoid1457 // parsing it here and then again in |extractDataStructures|,1458 // we only use the array length for now (fixes bug1157493.pdf).1459 hash.update(entry.length.toString());1460 }1461 }1462 }1463 var toUnicode = dict.get('ToUnicode') || baseDict.get('ToUnicode');1464 if (isStream(toUnicode)) {1465 var stream = toUnicode.str || toUnicode;1466 uint8array = stream.buffer ?1467 new Uint8Array(stream.buffer.buffer, 0, stream.bufferLength) :1468 new Uint8Array(stream.bytes.buffer,1469 stream.start, stream.end - stream.start);1470 hash.update(uint8array);1471 } else if (isName(toUnicode)) {1472 hash.update(toUnicode.name);1473 }1474 var widths = dict.get('Widths') || baseDict.get('Widths');1475 if (widths) {1476 uint8array = new Uint8Array(new Uint32Array(widths).buffer);1477 hash.update(uint8array);1478 }1479 }1480 return {1481 descriptor: descriptor,1482 dict: dict,1483 baseDict: baseDict,1484 composite: composite,1485 type: type.name,1486 hash: hash ? hash.hexdigest() : ''1487 };1488 },1489 translateFont: function PartialEvaluator_translateFont(preEvaluatedFont,1490 xref) {1491 var baseDict = preEvaluatedFont.baseDict;1492 var dict = preEvaluatedFont.dict;1493 var composite = preEvaluatedFont.composite;1494 var descriptor = preEvaluatedFont.descriptor;1495 var type = preEvaluatedFont.type;1496 var maxCharIndex = (composite ? 0xFFFF : 0xFF);1497 var properties;1498 if (!descriptor) {1499 if (type === 'Type3') {1500 // FontDescriptor is only required for Type3 fonts when the document1501 // is a tagged pdf. Create a barbebones one to get by.1502 descriptor = new Dict(null);1503 descriptor.set('FontName', Name.get(type));1504 } else {1505 // Before PDF 1.5 if the font was one of the base 14 fonts, having a1506 // FontDescriptor was not required.1507 // This case is here for compatibility.1508 var baseFontName = dict.get('BaseFont');1509 if (!isName(baseFontName)) {1510 error('Base font is not specified');1511 }1512 // Using base font name as a font name.1513 baseFontName = baseFontName.name.replace(/[,_]/g, '-');1514 var metrics = this.getBaseFontMetrics(baseFontName);1515 // Simulating descriptor flags attribute1516 var fontNameWoStyle = baseFontName.split('-')[0];1517 var flags =1518 (this.isSerifFont(fontNameWoStyle) ? FontFlags.Serif : 0) |1519 (metrics.monospace ? FontFlags.FixedPitch : 0) |1520 (symbolsFonts[fontNameWoStyle] ? FontFlags.Symbolic :1521 FontFlags.Nonsymbolic);1522 properties = {1523 type: type,1524 name: baseFontName,1525 widths: metrics.widths,1526 defaultWidth: metrics.defaultWidth,1527 flags: flags,1528 firstChar: 0,1529 lastChar: maxCharIndex1530 };1531 this.extractDataStructures(dict, dict, xref, properties);1532 properties.widths = this.buildCharCodeToWidth(metrics.widths,1533 properties);1534 return new Font(baseFontName, null, properties);1535 }1536 }1537 // According to the spec if 'FontDescriptor' is declared, 'FirstChar',1538 // 'LastChar' and 'Widths' should exist too, but some PDF encoders seem1539 // to ignore this rule when a variant of a standart font is used.1540 // TODO Fill the width array depending on which of the base font this is1541 // a variant.1542 var firstChar = (dict.get('FirstChar') || 0);1543 var lastChar = (dict.get('LastChar') || maxCharIndex);1544 var fontName = descriptor.get('FontName');1545 var baseFont = dict.get('BaseFont');1546 // Some bad PDFs have a string as the font name.1547 if (isString(fontName)) {1548 fontName = Name.get(fontName);1549 }1550 if (isString(baseFont)) {1551 baseFont = Name.get(baseFont);1552 }1553 if (type !== 'Type3') {1554 var fontNameStr = fontName && fontName.name;1555 var baseFontStr = baseFont && baseFont.name;1556 if (fontNameStr !== baseFontStr) {1557 info('The FontDescriptor\'s FontName is "' + fontNameStr +1558 '" but should be the same as the Font\'s BaseFont "' +1559 baseFontStr + '"');1560 // Workaround for cases where e.g. fontNameStr = 'Arial' and1561 // baseFontStr = 'Arial,Bold' (needed when no font file is embedded).1562 if (fontNameStr && baseFontStr &&1563 baseFontStr.indexOf(fontNameStr) === 0) {1564 fontName = baseFont;1565 }1566 }1567 }1568 fontName = (fontName || baseFont);1569 assert(isName(fontName), 'invalid font name');1570 var fontFile = descriptor.get('FontFile', 'FontFile2', 'FontFile3');1571 if (fontFile) {1572 if (fontFile.dict) {1573 var subtype = fontFile.dict.get('Subtype');1574 if (subtype) {1575 subtype = subtype.name;1576 }1577 var length1 = fontFile.dict.get('Length1');1578 var length2 = fontFile.dict.get('Length2');1579 }1580 }1581 properties = {1582 type: type,1583 name: fontName.name,1584 subtype: subtype,1585 file: fontFile,1586 length1: length1,1587 length2: length2,1588 loadedName: baseDict.loadedName,1589 composite: composite,1590 wideChars: composite,1591 fixedPitch: false,1592 fontMatrix: (dict.get('FontMatrix') || FONT_IDENTITY_MATRIX),1593 firstChar: firstChar || 0,1594 lastChar: (lastChar || maxCharIndex),1595 bbox: descriptor.get('FontBBox'),1596 ascent: descriptor.get('Ascent'),1597 descent: descriptor.get('Descent'),1598 xHeight: descriptor.get('XHeight'),1599 capHeight: descriptor.get('CapHeight'),1600 flags: descriptor.get('Flags'),1601 italicAngle: descriptor.get('ItalicAngle'),1602 coded: false1603 };1604 if (composite) {1605 var cidEncoding = baseDict.get('Encoding');1606 if (isName(cidEncoding)) {1607 properties.cidEncoding = cidEncoding.name;1608 }1609 properties.cMap = CMapFactory.create(cidEncoding,1610 { url: PDFJS.cMapUrl, packed: PDFJS.cMapPacked }, null);1611 properties.vertical = properties.cMap.vertical;1612 }1613 this.extractDataStructures(dict, baseDict, xref, properties);1614 this.extractWidths(dict, xref, descriptor, properties);1615 if (type === 'Type3') {1616 properties.isType3Font = true;1617 }1618 return new Font(fontName.name, fontFile, properties);1619 }1620 };1621 return PartialEvaluator;1622})();1623var TranslatedFont = (function TranslatedFontClosure() {1624 function TranslatedFont(loadedName, font, dict) {1625 this.loadedName = loadedName;1626 this.font = font;1627 this.dict = dict;1628 this.type3Loaded = null;1629 this.sent = false;1630 }1631 TranslatedFont.prototype = {1632 send: function (handler) {1633 if (this.sent) {1634 return;1635 }1636 var fontData = this.font.exportData();1637 handler.send('commonobj', [1638 this.loadedName,...
Using AI Code Generation
1var wptext2pdf = require("wptext2pdf");2var pdf = new wptext2pdf();3pdf.TranslatedFont("fonts/arial.ttf", "fonts/arial-unicode.ttf");4var wptext2pdf = require("wptext2pdf");5var pdf = new wptext2pdf();6pdf.TranslatedFont("fonts/arial.ttf", "fonts/arial-unicode.ttf");7var wptext2pdf = require("wptext2pdf");8var pdf = new wptext2pdf();9pdf.TranslatedFont("fonts/arial.ttf", "fonts/arial-unicode.ttf");10var wptext2pdf = require("wptext2pdf");11var pdf = new wptext2pdf();12pdf.TranslatedFont("fonts/arial.ttf", "fonts/arial-unicode.ttf");13var wptext2pdf = require("wptext2pdf");14var pdf = new wptext2pdf();15pdf.TranslatedFont("fonts/arial.ttf", "fonts/arial-unicode.ttf");16var wptext2pdf = require("wptext2pdf");17var pdf = new wptext2pdf();18pdf.TranslatedFont("fonts/arial.ttf", "fonts/arial-unicode.ttf");19var wptext2pdf = require("wptext2pdf");20var pdf = new wptext2pdf();21pdf.TranslatedFont("fonts/arial.ttf", "fonts/arial-unicode.ttf");22var wptext2pdf = require("wptext2pdf");23var pdf = new wptext2pdf();24pdf.TranslatedFont("fonts/arial.ttf", "fonts/arial-unicode.ttf");
Using AI Code Generation
1var wptools = require('wptools');2var page = wptools.page('Barack Obama');3page.setLang('fr').then(function(page){4 console.log(page.translatedFont());5});6{ 'font-family': 'Times New Roman,Times,serif',7 'line-height': '1.4em' }8var wptools = require('wptools');9var page = wptools.page('Barack Obama');10page.setLang('fr').then(function(page){11 console.log(page.translatedFont());12});13{ 'font-family': 'Times New Roman,Times,serif',14 'line-height': '1.4em' }15var wptools = require('wptools');16var page = wptools.page('Barack Obama');17page.setLang('fr').then(function(page){18 console.log(page.translatedFont());19});20{ 'font-family': 'Times New Roman,Times,serif',21 'line-height': '1.4em' }22var wptools = require('wptools');23var page = wptools.page('Barack Obama');24page.setLang('fr').then(function(page){25 console.log(page.translatedFont());26});27{ 'font-family': 'Times New Roman,Times,serif',28 'line-height': '1.4em' }29var wptools = require('wptools');30var page = wptools.page('Barack Obama');31page.setLang('fr').then(function(page){32 console.log(page.translatedFont());33});34{ 'font-family': 'Times New Roman,Times,serif',35 'line-height': '1.4em' }
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!!