/* global jsPDF */
/**
* @name utf8
* @module
*/
(function (jsPDF) {
'use strict';
var jsPDFAPI = jsPDF.API;
/***************************************************************************************************/
/* function : pdfEscape16 */
/* comment : The character id of a 2-byte string is converted to a hexadecimal number by obtaining */
/* the corresponding glyph id and width, and then adding padding to the string. */
/***************************************************************************************************/
var pdfEscape16 = jsPDFAPI.pdfEscape16 = function (text, font) {
var widths = font.metadata.Unicode.widths;
var padz = ["", "0", "00", "000", "0000"];
var ar = [""];
for (var i = 0, l = text.length, t; i < l; ++i) {
t = font.metadata.characterToGlyph(text.charCodeAt(i));
font.metadata.glyIdsUsed.push(t);
font.metadata.toUnicode[t] = text.charCodeAt(i);
if (widths.indexOf(t) == -1) {
widths.push(t);
widths.push([parseInt(font.metadata.widthOfGlyph(t), 10)]);
}
if (t == '0') { //Spaces are not allowed in cmap.
return ar.join("");
} else {
t = t.toString(16);
ar.push(padz[4 - t.length], t);
}
}
return ar.join("");
};
var toUnicodeCmap = function (map) {
var code, codes, range, unicode, unicodeMap, _i, _len;
unicodeMap = '/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo <<\n /Registry (Adobe)\n /Ordering (UCS)\n /Supplement 0\n>> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000><ffff>\nendcodespacerange';
codes = Object.keys(map).sort(function (a, b) {
return a - b;
});
range = [];
for (_i = 0, _len = codes.length; _i < _len; _i++) {
code = codes[_i];
if (range.length >= 100) {
unicodeMap += "\n" + range.length + " beginbfchar\n" + range.join('\n') + "\nendbfchar";
range = [];
}
if (map[code] !== undefined && map[code] !== null && typeof map[code].toString === "function") {
unicode = ('0000' + map[code].toString(16)).slice(-4);
code = ('0000' + (+code).toString(16)).slice(-4);
range.push("<" + code + "><" + unicode + ">");
}
}
if (range.length) {
unicodeMap += "\n" + range.length + " beginbfchar\n" + range.join('\n') + "\nendbfchar\n";
}
unicodeMap += 'endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend';
return unicodeMap;
};
var identityHFunction = function (options) {
var font = options.font;
var out = options.out;
var newObject = options.newObject;
var putStream = options.putStream;
var pdfEscapeWithNeededParanthesis = options.pdfEscapeWithNeededParanthesis;
if ((font.metadata instanceof jsPDF.API.TTFFont) && (font.encoding === 'Identity-H')) { //Tag with Identity-H
var widths = font.metadata.Unicode.widths;
var data = font.metadata.subset.encode(font.metadata.glyIdsUsed, 1);
var pdfOutput = data;
var pdfOutput2 = "";
for (var i = 0; i < pdfOutput.length; i++) {
pdfOutput2 += String.fromCharCode(pdfOutput[i]);
}
var fontTable = newObject();
putStream({data: pdfOutput2, addLength1: true});
out('endobj');
var cmap = newObject();
var cmapData = toUnicodeCmap(font.metadata.toUnicode);
putStream({data: cmapData, addLength1: true});
out('endobj');
var fontDescriptor = newObject();
out('<<');
out('/Type /FontDescriptor');
out('/FontName /' + pdfEscapeWithNeededParanthesis(font.fontName));
out('/FontFile2 ' + fontTable + ' 0 R');
out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));
out('/Flags ' + font.metadata.flags);
out('/StemV ' + font.metadata.stemV);
out('/ItalicAngle ' + font.metadata.italicAngle);
out('/Ascent ' + font.metadata.ascender);
out('/Descent ' + font.metadata.decender);
out('/CapHeight ' + font.metadata.capHeight);
out('>>');
out('endobj');
var DescendantFont = newObject();
out('<<');
out('/Type /Font');
out('/BaseFont /' + pdfEscapeWithNeededParanthesis(font.fontName));
out('/FontDescriptor ' + fontDescriptor + ' 0 R');
out('/W ' + jsPDF.API.PDFObject.convert(widths));
out('/CIDToGIDMap /Identity');
out('/DW 1000');
out('/Subtype /CIDFontType2');
out('/CIDSystemInfo');
out('<<');
out('/Supplement 0');
out('/Registry (Adobe)');
out('/Ordering (' + font.encoding + ')');
out('>>');
out('>>');
out('endobj');
font.objectNumber = newObject();
out('<<');
out('/Type /Font');
out('/Subtype /Type0');
out('/ToUnicode ' + cmap + ' 0 R');
out('/BaseFont /' + font.fontName);
out('/Encoding /' + font.encoding);
out('/DescendantFonts [' + DescendantFont + ' 0 R]');
out('>>');
out('endobj');
font.isAlreadyPutted = true;
}
}
jsPDFAPI.events.push([
'putFont'
,function(args) {
identityHFunction(args);
}]);
var winAnsiEncodingFunction = function (options) {
var font = options.font;
var out = options.out;
var newObject = options.newObject;
var putStream = options.putStream;
var pdfEscapeWithNeededParanthesis = options.pdfEscapeWithNeededParanthesis;
if ((font.metadata instanceof jsPDF.API.TTFFont) && font.encoding === 'WinAnsiEncoding') { //Tag with WinAnsi encoding
var data = font.metadata.rawData;
var pdfOutput = data;
var pdfOutput2 = "";
for (var i = 0; i < pdfOutput.length; i++) {
pdfOutput2 += String.fromCharCode(pdfOutput[i]);
}
var fontTable = newObject();
putStream({data: pdfOutput2,addLength1: true});
out('endobj');
var cmap = newObject();
var cmapData = toUnicodeCmap(font.metadata.toUnicode);
putStream({data: cmapData, addLength1: true});
out('endobj');
var fontDescriptor = newObject();
out('<<');
out('/Descent ' + font.metadata.decender);
out('/CapHeight ' + font.metadata.capHeight);
out('/StemV ' + font.metadata.stemV);
out('/Type /FontDescriptor');
out('/FontFile2 ' + fontTable + ' 0 R');
out('/Flags 96');
out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));
out('/FontName /' + pdfEscapeWithNeededParanthesis(font.fontName));
out('/ItalicAngle ' + font.metadata.italicAngle);
out('/Ascent ' + font.metadata.ascender);
out('>>');
out('endobj');
font.objectNumber = newObject();
for (var j = 0; j < font.metadata.hmtx.widths.length; j++) {
font.metadata.hmtx.widths[j] = parseInt(font.metadata.hmtx.widths[j] * (1000 / font.metadata.head.unitsPerEm)); //Change the width of Em units to Point units.
}
out('<</Subtype/TrueType/Type/Font/ToUnicode ' + cmap + ' 0 R/BaseFont/' + font.fontName + '/FontDescriptor ' + fontDescriptor + ' 0 R' + '/Encoding/' + font.encoding + ' /FirstChar 29 /LastChar 255 /Widths ' + jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths) + '>>');
out('endobj');
font.isAlreadyPutted = true;
}
}
jsPDFAPI.events.push([
'putFont'
,function(args) {
winAnsiEncodingFunction(args);
}
]);
var utf8TextFunction = function (args) {
var text = args.text || '';
var x = args.x;
var y = args.y;
var options = args.options || {};
var mutex = args.mutex || {};
var pdfEscape = mutex.pdfEscape;
var activeFontKey = mutex.activeFontKey;
var fonts = mutex.fonts;
var key = activeFontKey;
var str = '',
s = 0,
cmapConfirm;
var strText = '';
var encoding = fonts[key].encoding;
if (fonts[key].encoding !== 'Identity-H') {
return {
text : text,
x : x,
y : y,
options: options,
mutex: mutex
};
}
strText = text;
key = activeFontKey;
if (Array.isArray(text)) {
strText = text[0];
}
for (s = 0; s < strText.length; s += 1) {
if (fonts[key].metadata.hasOwnProperty('cmap')) {
cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)];
/*
if (Object.prototype.toString.call(text) === '[object Array]') {
var i = 0;
// for (i = 0; i < text.length; i += 1) {
if (Object.prototype.toString.call(text[s]) === '[object Array]') {
cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s][0].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
} else {
}
//}
} else {
cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
}*/
}
if (!cmapConfirm) {
if (strText[s].charCodeAt(0) < 256 && fonts[key].metadata.hasOwnProperty('Unicode')) {
str += strText[s];
} else {
str += '';
}
} else {
str += strText[s];
}
}
var result = '';
if ((parseInt(key.slice(1)) < 14) || encoding === 'WinAnsiEncoding') { //For the default 13 font
result = pdfEscape(str, key).split('').map(function (cv) {return cv.charCodeAt(0).toString(16)}).join('');
} else if (encoding === 'Identity-H') {
result = pdfEscape16(str, fonts[key]);
}
mutex.isHex = true;
return {
text : result,
x : x,
y : y,
options: options,
mutex: mutex
};
}
var utf8EscapeFunction = function(parms) {
var text = parms.text || '',
x = parms.x,
y = parms.y,
options = parms.options,
mutex = parms.mutex;
var tmpText = [];
var args = {
text : text,
x : x,
y : y,
options: options,
mutex: mutex
};
if (Array.isArray(text)) {
var i = 0;
for (i = 0; i < text.length; i += 1) {
if (Array.isArray(text[i])) {
if (text[i].length === 3) {
tmpText.push([utf8TextFunction(Object.assign({}, args, {text: text[i][0]})).text, text[i][1], text[i][2]]);
} else {
tmpText.push(utf8TextFunction(Object.assign({}, args, {text: text[i]})).text);
}
} else {
tmpText.push(utf8TextFunction(Object.assign({}, args, {text: text[i]})).text);
}
}
parms.text = tmpText;
} else {
parms.text = utf8TextFunction(Object.assign({}, args, {text: text})).text;
}
}
jsPDFAPI.events.push([
'postProcessText'
,utf8EscapeFunction
]);
})(jsPDF);