commit
37a980ca28
2
Makefile
2
Makefile
@ -12,6 +12,8 @@ PDF_JS_FILES = \
|
|||||||
pdf.js \
|
pdf.js \
|
||||||
crypto.js \
|
crypto.js \
|
||||||
fonts.js \
|
fonts.js \
|
||||||
|
metrics.js \
|
||||||
|
charsets.js \
|
||||||
glyphlist.js \
|
glyphlist.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
101
charsets.js
Normal file
101
charsets.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
|
||||||
|
var ISOAdobeCharset = [
|
||||||
|
'.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar',
|
||||||
|
'percent', 'ampersand', 'quoteright', 'parenleft', 'parenright',
|
||||||
|
'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero',
|
||||||
|
'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight',
|
||||||
|
'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question',
|
||||||
|
'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
|
'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore',
|
||||||
|
'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
|
||||||
|
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
|
'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent',
|
||||||
|
'sterling', 'fraction', 'yen', 'florin', 'section', 'currency',
|
||||||
|
'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft',
|
||||||
|
'guilsinglright', 'fi', 'fl', 'endash', 'dagger', 'daggerdbl',
|
||||||
|
'periodcentered', 'paragraph', 'bullet', 'quotesinglbase',
|
||||||
|
'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis',
|
||||||
|
'perthousand', 'questiondown', 'grave', 'acute', 'circumflex', 'tilde',
|
||||||
|
'macron', 'breve', 'dotaccent', 'dieresis', 'ring', 'cedilla',
|
||||||
|
'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine',
|
||||||
|
'Lslash', 'Oslash', 'OE', 'ordmasculine', 'ae', 'dotlessi', 'lslash',
|
||||||
|
'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu',
|
||||||
|
'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter',
|
||||||
|
'divide', 'brokenbar', 'degree', 'thorn', 'threequarters', 'twosuperior',
|
||||||
|
'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright',
|
||||||
|
'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde',
|
||||||
|
'Ccedilla', 'Eacute', 'Ecircumflex', 'Edieresis', 'Egrave', 'Iacute',
|
||||||
|
'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex',
|
||||||
|
'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex',
|
||||||
|
'Udieresis', 'Ugrave', 'Yacute', 'Ydieresis', 'Zcaron', 'aacute',
|
||||||
|
'acircumflex', 'adieresis', 'agrave', 'aring', 'atilde', 'ccedilla',
|
||||||
|
'eacute', 'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex',
|
||||||
|
'idieresis', 'igrave', 'ntilde', 'oacute', 'ocircumflex', 'odieresis',
|
||||||
|
'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis',
|
||||||
|
'ugrave', 'yacute', 'ydieresis', 'zcaron'
|
||||||
|
];
|
||||||
|
|
||||||
|
var ExpertCharset = [
|
||||||
|
'.notdef', 'space', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle',
|
||||||
|
'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior',
|
||||||
|
'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma',
|
||||||
|
'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle',
|
||||||
|
'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle',
|
||||||
|
'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle',
|
||||||
|
'colon', 'semicolon', 'commasuperior', 'threequartersemdash',
|
||||||
|
'periodsuperior', 'questionsmall', 'asuperior', 'bsuperior',
|
||||||
|
'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior',
|
||||||
|
'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior',
|
||||||
|
'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior',
|
||||||
|
'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall',
|
||||||
|
'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall',
|
||||||
|
'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall',
|
||||||
|
'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall',
|
||||||
|
'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary',
|
||||||
|
'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall', 'centoldstyle',
|
||||||
|
'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall',
|
||||||
|
'Brevesmall', 'Caronsmall', 'Dotaccentsmall', 'Macronsmall',
|
||||||
|
'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall',
|
||||||
|
'Cedillasmall', 'onequarter', 'onehalf', 'threequarters',
|
||||||
|
'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths',
|
||||||
|
'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior',
|
||||||
|
'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior',
|
||||||
|
'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior',
|
||||||
|
'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior',
|
||||||
|
'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior',
|
||||||
|
'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior',
|
||||||
|
'periodinferior', 'commainferior', 'Agravesmall', 'Aacutesmall',
|
||||||
|
'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', 'Aringsmall',
|
||||||
|
'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall',
|
||||||
|
'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall',
|
||||||
|
'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall',
|
||||||
|
'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall',
|
||||||
|
'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall',
|
||||||
|
'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall',
|
||||||
|
'Ydieresissmall'
|
||||||
|
];
|
||||||
|
|
||||||
|
var ExpertSubsetCharset = [
|
||||||
|
'.notdef', 'space', 'dollaroldstyle', 'dollarsuperior',
|
||||||
|
'parenleftsuperior', 'parenrightsuperior', 'twodotenleader',
|
||||||
|
'onedotenleader', 'comma', 'hyphen', 'period', 'fraction',
|
||||||
|
'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle',
|
||||||
|
'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle',
|
||||||
|
'eightoldstyle', 'nineoldstyle', 'colon', 'semicolon', 'commasuperior',
|
||||||
|
'threequartersemdash', 'periodsuperior', 'asuperior', 'bsuperior',
|
||||||
|
'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior',
|
||||||
|
'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior',
|
||||||
|
'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior',
|
||||||
|
'parenrightinferior', 'hyphensuperior', 'colonmonetary', 'onefitted',
|
||||||
|
'rupiah', 'centoldstyle', 'figuredash', 'hypheninferior', 'onequarter',
|
||||||
|
'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths',
|
||||||
|
'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior',
|
||||||
|
'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior',
|
||||||
|
'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior',
|
||||||
|
'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior',
|
||||||
|
'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior',
|
||||||
|
'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior',
|
||||||
|
'periodinferior', 'commainferior'
|
||||||
|
];
|
||||||
|
|
122
fonts.js
122
fonts.js
@ -447,13 +447,14 @@ var Font = (function Font() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var data;
|
var data;
|
||||||
switch (properties.type) {
|
var type = properties.type;
|
||||||
|
switch (type) {
|
||||||
case 'Type1':
|
case 'Type1':
|
||||||
case 'CIDFontType0':
|
case 'CIDFontType0':
|
||||||
this.mimetype = 'font/opentype';
|
this.mimetype = 'font/opentype';
|
||||||
|
|
||||||
var subtype = properties.subtype;
|
var subtype = properties.subtype;
|
||||||
var cff = (subtype === 'Type1C') ?
|
var cff = (subtype == 'Type1C' || subtype == 'CIDFontType0C') ?
|
||||||
new Type2CFF(file, properties) : new CFF(name, file, properties);
|
new Type2CFF(file, properties) : new CFF(name, file, properties);
|
||||||
|
|
||||||
// Wrap the CFF data inside an OTF font file
|
// Wrap the CFF data inside an OTF font file
|
||||||
@ -475,7 +476,7 @@ var Font = (function Font() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.type = properties.type;
|
this.type = type;
|
||||||
this.textMatrix = properties.textMatrix;
|
this.textMatrix = properties.textMatrix;
|
||||||
this.defaultWidth = properties.defaultWidth;
|
this.defaultWidth = properties.defaultWidth;
|
||||||
this.loadedName = getUniqueName();
|
this.loadedName = getUniqueName();
|
||||||
@ -2387,16 +2388,21 @@ var Type2CFF = (function() {
|
|||||||
|
|
||||||
var strings = this.getStrings(stringIndex);
|
var strings = this.getStrings(stringIndex);
|
||||||
|
|
||||||
var baseDict = this.parseDict(dictIndex.get(0));
|
var baseDict = this.parseDict(dictIndex.get(0).data);
|
||||||
var topDict = this.getTopDict(baseDict, strings);
|
var topDict = this.getTopDict(baseDict, strings);
|
||||||
|
|
||||||
var bytes = this.bytes;
|
var bytes = this.bytes;
|
||||||
|
|
||||||
|
var privateDict = {};
|
||||||
var privateInfo = topDict.Private;
|
var privateInfo = topDict.Private;
|
||||||
var privOffset = privateInfo[1], privLength = privateInfo[0];
|
if (privateInfo) {
|
||||||
var privBytes = bytes.subarray(privOffset, privOffset + privLength);
|
var privOffset = privateInfo[1], privLength = privateInfo[0];
|
||||||
baseDict = this.parseDict(privBytes);
|
var privBytes = bytes.subarray(privOffset, privOffset + privLength);
|
||||||
var privDict = this.getPrivDict(baseDict, strings);
|
baseDict = this.parseDict(privBytes);
|
||||||
|
privateDict = this.getPrivDict(baseDict, strings);
|
||||||
|
} else {
|
||||||
|
privateDict.defaultWidthX = properties.defaultWidth;
|
||||||
|
}
|
||||||
|
|
||||||
var charStrings = this.parseIndex(topDict.CharStrings);
|
var charStrings = this.parseIndex(topDict.CharStrings);
|
||||||
var charset = this.parseCharsets(topDict.charset,
|
var charset = this.parseCharsets(topDict.charset,
|
||||||
@ -2412,10 +2418,37 @@ var Type2CFF = (function() {
|
|||||||
if (hasSupplement)
|
if (hasSupplement)
|
||||||
bytes[topDict.Encoding] = 0;
|
bytes[topDict.Encoding] = 0;
|
||||||
|
|
||||||
|
// The CFF specification state that the 'dotsection' command
|
||||||
|
// (12, 0) is deprecated and treated as a no-op, but all Type2
|
||||||
|
// charstrings processors should support them. Unfortunately
|
||||||
|
// the font sanitizer don't. As a workaround the sequence (12, 0)
|
||||||
|
// is replaced by a useless (0, hmoveto).
|
||||||
|
var count = charStrings.length;
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
var charstring = charStrings.get(i);
|
||||||
|
|
||||||
|
var start = charstring.start;
|
||||||
|
var data = charstring.data;
|
||||||
|
var length = data.length;
|
||||||
|
for (var j = 0; j <= length; j) {
|
||||||
|
var value = data[j++];
|
||||||
|
if (value == 12 && data[j++] == 0) {
|
||||||
|
bytes[start + j - 2] = 139;
|
||||||
|
bytes[start + j - 1] = 22;
|
||||||
|
} else if (value === 28) {
|
||||||
|
j += 2;
|
||||||
|
} else if (value >= 247 && value <= 254) {
|
||||||
|
j++;
|
||||||
|
} else if (value == 255) {
|
||||||
|
j += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// charstrings contains info about glyphs (one element per glyph
|
// charstrings contains info about glyphs (one element per glyph
|
||||||
// containing mappings for {unicode, width})
|
// containing mappings for {unicode, width})
|
||||||
var charstrings = this.getCharStrings(charset, charStrings,
|
var charstrings = this.getCharStrings(charset, charStrings,
|
||||||
privDict, this.properties);
|
privateDict, this.properties);
|
||||||
|
|
||||||
// create the mapping between charstring and glyph id
|
// create the mapping between charstring and glyph id
|
||||||
var glyphIds = [];
|
var glyphIds = [];
|
||||||
@ -2432,10 +2465,8 @@ var Type2CFF = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getCharStrings: function cff_charstrings(charsets, charStrings,
|
getCharStrings: function cff_charstrings(charsets, charStrings,
|
||||||
privDict, properties) {
|
privateDict, properties) {
|
||||||
var defaultWidth = privDict['defaultWidthX'];
|
var defaultWidth = privateDict['defaultWidthX'];
|
||||||
var nominalWidth = privDict['nominalWidthX'];
|
|
||||||
|
|
||||||
var charstrings = [];
|
var charstrings = [];
|
||||||
var differences = properties.differences;
|
var differences = properties.differences;
|
||||||
var index = 0;
|
var index = 0;
|
||||||
@ -2492,8 +2523,8 @@ var Type2CFF = (function() {
|
|||||||
|
|
||||||
if (pos == 0 || pos == 1) {
|
if (pos == 0 || pos == 1) {
|
||||||
var gid = 1;
|
var gid = 1;
|
||||||
var baseEncoding =
|
var baseEncoding = pos ? Encodings.ExpertEncoding.slice() :
|
||||||
pos ? Encodings.ExpertEncoding : Encodings.StandardEncoding;
|
Encodings.StandardEncoding.slice();
|
||||||
for (var i = 0; i < charset.length; i++) {
|
for (var i = 0; i < charset.length; i++) {
|
||||||
var index = baseEncoding.indexOf(charset[i]);
|
var index = baseEncoding.indexOf(charset[i]);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
@ -2538,37 +2569,42 @@ var Type2CFF = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
parseCharsets: function cff_parsecharsets(pos, length, strings) {
|
parseCharsets: function cff_parsecharsets(pos, length, strings) {
|
||||||
|
if (pos == 0) {
|
||||||
|
return ISOAdobeCharset.slice();
|
||||||
|
} else if (pos == 1) {
|
||||||
|
return ExpertCharset.slice();
|
||||||
|
} else if (pos == 2) {
|
||||||
|
return ExpertSubsetCharset.slice();
|
||||||
|
}
|
||||||
|
|
||||||
var bytes = this.bytes;
|
var bytes = this.bytes;
|
||||||
var format = bytes[pos++];
|
var format = bytes[pos++];
|
||||||
var charset = ['.notdef'];
|
var charset = ['.notdef'];
|
||||||
|
|
||||||
// subtract 1 for the .notdef glyph
|
// subtract 1 for the .notdef glyph
|
||||||
length -= 1;
|
length -= 1;
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 0:
|
case 0:
|
||||||
for (var i = 0; i < length; ++i) {
|
for (var i = 0; i < length; i++) {
|
||||||
var id = bytes[pos++];
|
var sid = (bytes[pos++] << 8) | bytes[pos++];
|
||||||
id = (id << 8) | bytes[pos++];
|
charset.push(strings[sid]);
|
||||||
charset.push(strings[id]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
while (charset.length <= length) {
|
while (charset.length <= length) {
|
||||||
var first = bytes[pos++];
|
var sid = (bytes[pos++] << 8) | bytes[pos++];
|
||||||
first = (first << 8) | bytes[pos++];
|
var count = bytes[pos++];
|
||||||
var numLeft = bytes[pos++];
|
for (var i = 0; i <= count; i++)
|
||||||
for (var i = 0; i <= numLeft; ++i)
|
charset.push(strings[sid++]);
|
||||||
charset.push(strings[first++]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
while (charset.length <= length) {
|
while (charset.length <= length) {
|
||||||
var first = bytes[pos++];
|
var sid = (bytes[pos++] << 8) | bytes[pos++];
|
||||||
first = (first << 8) | bytes[pos++];
|
var count = (bytes[pos++] << 8) | bytes[pos++];
|
||||||
var numLeft = bytes[pos++];
|
for (var i = 0; i <= count; i++)
|
||||||
numLeft = (numLeft << 8) | bytes[pos++];
|
charset.push(strings[sid++]);
|
||||||
for (var i = 0; i <= numLeft; ++i)
|
|
||||||
charset.push(strings[first++]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2643,20 +2679,20 @@ var Type2CFF = (function() {
|
|||||||
}
|
}
|
||||||
return dict;
|
return dict;
|
||||||
},
|
},
|
||||||
getStrings: function cff_getstrings(stringIndex) {
|
getStrings: function cff_getStrings(stringIndex) {
|
||||||
function bytesToString(bytesArr) {
|
function bytesToString(bytesArray) {
|
||||||
var s = '';
|
var str = '';
|
||||||
for (var i = 0, ii = bytesArr.length; i < ii; ++i)
|
for (var i = 0, length = bytesArray.length; i < length; i++)
|
||||||
s += String.fromCharCode(bytesArr[i]);
|
str += String.fromCharCode(bytesArray[i]);
|
||||||
return s;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stringArray = [];
|
var stringArray = [];
|
||||||
for (var i = 0, ii = CFFStrings.length; i < ii; ++i)
|
for (var i = 0, length = CFFStrings.length; i < length; i++)
|
||||||
stringArray.push(CFFStrings[i]);
|
stringArray.push(CFFStrings[i]);
|
||||||
|
|
||||||
for (var i = 0, ii = stringIndex.length; i < ii; ++i)
|
for (var i = 0, length = stringIndex.length; i < length; i++)
|
||||||
stringArray.push(bytesToString(stringIndex.get(i)));
|
stringArray.push(bytesToString(stringIndex.get(i).data));
|
||||||
|
|
||||||
return stringArray;
|
return stringArray;
|
||||||
},
|
},
|
||||||
@ -2702,7 +2738,7 @@ var Type2CFF = (function() {
|
|||||||
} else if (value <= 254) {
|
} else if (value <= 254) {
|
||||||
return -((value - 251) * 256) - dict[pos++] - 108;
|
return -((value - 251) * 256) - dict[pos++] - 108;
|
||||||
} else {
|
} else {
|
||||||
error('Incorrect byte');
|
error('255 is not a valid DICT command');
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2779,7 +2815,11 @@ var Type2CFF = (function() {
|
|||||||
|
|
||||||
var start = offsets[index];
|
var start = offsets[index];
|
||||||
var end = offsets[index + 1];
|
var end = offsets[index + 1];
|
||||||
return bytes.subarray(start, end);
|
return {
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
data: bytes.subarray(start, end)
|
||||||
|
};
|
||||||
},
|
},
|
||||||
length: count,
|
length: count,
|
||||||
endPos: end
|
endPos: end
|
||||||
|
9
pdf.js
9
pdf.js
@ -4280,8 +4280,9 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||||||
properties.widths = glyphsWidths;
|
properties.widths = glyphsWidths;
|
||||||
|
|
||||||
var cidToGidMap = dict.get('CIDToGIDMap');
|
var cidToGidMap = dict.get('CIDToGIDMap');
|
||||||
if (!cidToGidMap || !IsRef(cidToGidMap))
|
if (!cidToGidMap || !IsRef(cidToGidMap)) {
|
||||||
return GlyphsUnicode;
|
return Object.create(GlyphsUnicode);
|
||||||
|
}
|
||||||
|
|
||||||
// Extract the encoding from the CIDToGIDMap
|
// Extract the encoding from the CIDToGIDMap
|
||||||
var glyphsStream = xref.fetchIfRef(cidToGidMap);
|
var glyphsStream = xref.fetchIfRef(cidToGidMap);
|
||||||
@ -4318,7 +4319,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||||||
'9.7.5.3');
|
'9.7.5.3');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GlyphsUnicode;
|
return Object.create(GlyphsUnicode);
|
||||||
}
|
}
|
||||||
|
|
||||||
var differences = properties.differences;
|
var differences = properties.differences;
|
||||||
@ -4494,7 +4495,7 @@ var PartialEvaluator = (function partialEvaluator() {
|
|||||||
var map = {};
|
var map = {};
|
||||||
if (/^Symbol(-?(Bold|Italic))*$/.test(name)) {
|
if (/^Symbol(-?(Bold|Italic))*$/.test(name)) {
|
||||||
// special case for symbols
|
// special case for symbols
|
||||||
var encoding = Encodings.symbolsEncoding;
|
var encoding = Encodings.symbolsEncoding.slice();
|
||||||
for (var i = 0, n = encoding.length, j; i < n; i++) {
|
for (var i = 0, n = encoding.length, j; i < n; i++) {
|
||||||
if (!(j = encoding[i]))
|
if (!(j = encoding[i]))
|
||||||
continue;
|
continue;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<script type="text/javascript" src="/crypto.js"></script>
|
<script type="text/javascript" src="/crypto.js"></script>
|
||||||
<script type="text/javascript" src="/glyphlist.js"></script>
|
<script type="text/javascript" src="/glyphlist.js"></script>
|
||||||
<script type="text/javascript" src="/metrics.js"></script>
|
<script type="text/javascript" src="/metrics.js"></script>
|
||||||
|
<script type="text/javascript" src="/charsets.js"></script>
|
||||||
<script type="text/javascript" src="driver.js"></script>
|
<script type="text/javascript" src="driver.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -3,400 +3,6 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var CFFStrings = [
|
|
||||||
'.notdef',
|
|
||||||
'space',
|
|
||||||
'exclam',
|
|
||||||
'quotedbl',
|
|
||||||
'numbersign',
|
|
||||||
'dollar',
|
|
||||||
'percent',
|
|
||||||
'ampersand',
|
|
||||||
'quoteright',
|
|
||||||
'parenleft',
|
|
||||||
'parenright',
|
|
||||||
'asterisk',
|
|
||||||
'plus',
|
|
||||||
'comma',
|
|
||||||
'hyphen',
|
|
||||||
'period',
|
|
||||||
'slash',
|
|
||||||
'zero',
|
|
||||||
'one',
|
|
||||||
'two',
|
|
||||||
'three',
|
|
||||||
'four',
|
|
||||||
'five',
|
|
||||||
'six',
|
|
||||||
'seven',
|
|
||||||
'eight',
|
|
||||||
'nine',
|
|
||||||
'colon',
|
|
||||||
'semicolon',
|
|
||||||
'less',
|
|
||||||
'equal',
|
|
||||||
'greater',
|
|
||||||
'question',
|
|
||||||
'at',
|
|
||||||
'A',
|
|
||||||
'B',
|
|
||||||
'C',
|
|
||||||
'D',
|
|
||||||
'E',
|
|
||||||
'F',
|
|
||||||
'G',
|
|
||||||
'H',
|
|
||||||
'I',
|
|
||||||
'J',
|
|
||||||
'K',
|
|
||||||
'L',
|
|
||||||
'M',
|
|
||||||
'N',
|
|
||||||
'O',
|
|
||||||
'P',
|
|
||||||
'Q',
|
|
||||||
'R',
|
|
||||||
'S',
|
|
||||||
'T',
|
|
||||||
'U',
|
|
||||||
'V',
|
|
||||||
'W',
|
|
||||||
'X',
|
|
||||||
'Y',
|
|
||||||
'Z',
|
|
||||||
'bracketleft',
|
|
||||||
'backslash',
|
|
||||||
'bracketright',
|
|
||||||
'asciicircum',
|
|
||||||
'underscore',
|
|
||||||
'quoteleft',
|
|
||||||
'a',
|
|
||||||
'b',
|
|
||||||
'c',
|
|
||||||
'd',
|
|
||||||
'e',
|
|
||||||
'f',
|
|
||||||
'g',
|
|
||||||
'h',
|
|
||||||
'i',
|
|
||||||
'j',
|
|
||||||
'k',
|
|
||||||
'l',
|
|
||||||
'm',
|
|
||||||
'n',
|
|
||||||
'o',
|
|
||||||
'p',
|
|
||||||
'q',
|
|
||||||
'r',
|
|
||||||
's',
|
|
||||||
't',
|
|
||||||
'u',
|
|
||||||
'v',
|
|
||||||
'w',
|
|
||||||
'x',
|
|
||||||
'y',
|
|
||||||
'z',
|
|
||||||
'braceleft',
|
|
||||||
'bar',
|
|
||||||
'braceright',
|
|
||||||
'asciitilde',
|
|
||||||
'exclamdown',
|
|
||||||
'cent',
|
|
||||||
'sterling',
|
|
||||||
'fraction',
|
|
||||||
'yen',
|
|
||||||
'florin',
|
|
||||||
'section',
|
|
||||||
'currency',
|
|
||||||
'quotesingle',
|
|
||||||
'quotedblleft',
|
|
||||||
'guillemotleft',
|
|
||||||
'guilsinglleft',
|
|
||||||
'guilsinglright',
|
|
||||||
'fi',
|
|
||||||
'fl',
|
|
||||||
'endash',
|
|
||||||
'dagger',
|
|
||||||
'daggerdbl',
|
|
||||||
'periodcentered',
|
|
||||||
'paragraph',
|
|
||||||
'bullet',
|
|
||||||
'quotesinglbase',
|
|
||||||
'quotedblbase',
|
|
||||||
'quotedblright',
|
|
||||||
'guillemotright',
|
|
||||||
'ellipsis',
|
|
||||||
'perthousand',
|
|
||||||
'questiondown',
|
|
||||||
'grave',
|
|
||||||
'acute',
|
|
||||||
'circumflex',
|
|
||||||
'tilde',
|
|
||||||
'macron',
|
|
||||||
'breve',
|
|
||||||
'dotaccent',
|
|
||||||
'dieresis',
|
|
||||||
'ring',
|
|
||||||
'cedilla',
|
|
||||||
'hungarumlaut',
|
|
||||||
'ogonek',
|
|
||||||
'caron',
|
|
||||||
'emdash',
|
|
||||||
'AE',
|
|
||||||
'ordfeminine',
|
|
||||||
'Lslash',
|
|
||||||
'Oslash',
|
|
||||||
'OE',
|
|
||||||
'ordmasculine',
|
|
||||||
'ae',
|
|
||||||
'dotlessi',
|
|
||||||
'lslash',
|
|
||||||
'oslash',
|
|
||||||
'oe',
|
|
||||||
'germandbls',
|
|
||||||
'onesuperior',
|
|
||||||
'logicalnot',
|
|
||||||
'mu',
|
|
||||||
'trademark',
|
|
||||||
'Eth',
|
|
||||||
'onehalf',
|
|
||||||
'plusminus',
|
|
||||||
'Thorn',
|
|
||||||
'onequarter',
|
|
||||||
'divide',
|
|
||||||
'brokenbar',
|
|
||||||
'degree',
|
|
||||||
'thorn',
|
|
||||||
'threequarters',
|
|
||||||
'twosuperior',
|
|
||||||
'registered',
|
|
||||||
'minus',
|
|
||||||
'eth',
|
|
||||||
'multiply',
|
|
||||||
'threesuperior',
|
|
||||||
'copyright',
|
|
||||||
'Aacute',
|
|
||||||
'Acircumflex',
|
|
||||||
'Adieresis',
|
|
||||||
'Agrave',
|
|
||||||
'Aring',
|
|
||||||
'Atilde',
|
|
||||||
'Ccedilla',
|
|
||||||
'Eacute',
|
|
||||||
'Ecircumflex',
|
|
||||||
'Edieresis',
|
|
||||||
'Egrave',
|
|
||||||
'Iacute',
|
|
||||||
'Icircumflex',
|
|
||||||
'Idieresis',
|
|
||||||
'Igrave',
|
|
||||||
'Ntilde',
|
|
||||||
'Oacute',
|
|
||||||
'Ocircumflex',
|
|
||||||
'Odieresis',
|
|
||||||
'Ograve',
|
|
||||||
'Otilde',
|
|
||||||
'Scaron',
|
|
||||||
'Uacute',
|
|
||||||
'Ucircumflex',
|
|
||||||
'Udieresis',
|
|
||||||
'Ugrave',
|
|
||||||
'Yacute',
|
|
||||||
'Ydieresis',
|
|
||||||
'Zcaron',
|
|
||||||
'aacute',
|
|
||||||
'acircumflex',
|
|
||||||
'adieresis',
|
|
||||||
'agrave',
|
|
||||||
'aring',
|
|
||||||
'atilde',
|
|
||||||
'ccedilla',
|
|
||||||
'eacute',
|
|
||||||
'ecircumflex',
|
|
||||||
'edieresis',
|
|
||||||
'egrave',
|
|
||||||
'iacute',
|
|
||||||
'icircumflex',
|
|
||||||
'idieresis',
|
|
||||||
'igrave',
|
|
||||||
'ntilde',
|
|
||||||
'oacute',
|
|
||||||
'ocircumflex',
|
|
||||||
'odieresis',
|
|
||||||
'ograve',
|
|
||||||
'otilde',
|
|
||||||
'scaron',
|
|
||||||
'uacute',
|
|
||||||
'ucircumflex',
|
|
||||||
'udieresis',
|
|
||||||
'ugrave',
|
|
||||||
'yacute',
|
|
||||||
'ydieresis',
|
|
||||||
'zcaron',
|
|
||||||
'exclamsmall',
|
|
||||||
'Hungarumlautsmall',
|
|
||||||
'dollaroldstyle',
|
|
||||||
'dollarsuperior',
|
|
||||||
'ampersandsmall',
|
|
||||||
'Acutesmall',
|
|
||||||
'parenleftsuperior',
|
|
||||||
'parenrightsuperior',
|
|
||||||
'266 ff',
|
|
||||||
'onedotenleader',
|
|
||||||
'zerooldstyle',
|
|
||||||
'oneoldstyle',
|
|
||||||
'twooldstyle',
|
|
||||||
'threeoldstyle',
|
|
||||||
'fouroldstyle',
|
|
||||||
'fiveoldstyle',
|
|
||||||
'sixoldstyle',
|
|
||||||
'sevenoldstyle',
|
|
||||||
'eightoldstyle',
|
|
||||||
'nineoldstyle',
|
|
||||||
'commasuperior',
|
|
||||||
'threequartersemdash',
|
|
||||||
'periodsuperior',
|
|
||||||
'questionsmall',
|
|
||||||
'asuperior',
|
|
||||||
'bsuperior',
|
|
||||||
'centsuperior',
|
|
||||||
'dsuperior',
|
|
||||||
'esuperior',
|
|
||||||
'isuperior',
|
|
||||||
'lsuperior',
|
|
||||||
'msuperior',
|
|
||||||
'nsuperior',
|
|
||||||
'osuperior',
|
|
||||||
'rsuperior',
|
|
||||||
'ssuperior',
|
|
||||||
'tsuperior',
|
|
||||||
'ff',
|
|
||||||
'ffi',
|
|
||||||
'ffl',
|
|
||||||
'parenleftinferior',
|
|
||||||
'parenrightinferior',
|
|
||||||
'Circumflexsmall',
|
|
||||||
'hyphensuperior',
|
|
||||||
'Gravesmall',
|
|
||||||
'Asmall',
|
|
||||||
'Bsmall',
|
|
||||||
'Csmall',
|
|
||||||
'Dsmall',
|
|
||||||
'Esmall',
|
|
||||||
'Fsmall',
|
|
||||||
'Gsmall',
|
|
||||||
'Hsmall',
|
|
||||||
'Ismall',
|
|
||||||
'Jsmall',
|
|
||||||
'Ksmall',
|
|
||||||
'Lsmall',
|
|
||||||
'Msmall',
|
|
||||||
'Nsmall',
|
|
||||||
'Osmall',
|
|
||||||
'Psmall',
|
|
||||||
'Qsmall',
|
|
||||||
'Rsmall',
|
|
||||||
'Ssmall',
|
|
||||||
'Tsmall',
|
|
||||||
'Usmall',
|
|
||||||
'Vsmall',
|
|
||||||
'Wsmall',
|
|
||||||
'Xsmall',
|
|
||||||
'Ysmall',
|
|
||||||
'Zsmall',
|
|
||||||
'colonmonetary',
|
|
||||||
'onefitted',
|
|
||||||
'rupiah',
|
|
||||||
'Tildesmall',
|
|
||||||
'exclamdownsmall',
|
|
||||||
'centoldstyle',
|
|
||||||
'Lslashsmall',
|
|
||||||
'Scaronsmall',
|
|
||||||
'Zcaronsmall',
|
|
||||||
'Dieresissmall',
|
|
||||||
'Brevesmall',
|
|
||||||
'Caronsmall',
|
|
||||||
'Dotaccentsmall',
|
|
||||||
'Macronsmall',
|
|
||||||
'figuredash',
|
|
||||||
'hypheninferior',
|
|
||||||
'Ogoneksmall',
|
|
||||||
'Ringsmall',
|
|
||||||
'Cedillasmall',
|
|
||||||
'questiondownsmall',
|
|
||||||
'oneeighth',
|
|
||||||
'threeeighths',
|
|
||||||
'fiveeighths',
|
|
||||||
'seveneighths',
|
|
||||||
'onethird',
|
|
||||||
'twothirds',
|
|
||||||
'zerosuperior',
|
|
||||||
'foursuperior',
|
|
||||||
'fivesuperior',
|
|
||||||
'sixsuperior',
|
|
||||||
'sevensuperior',
|
|
||||||
'eightsuperior',
|
|
||||||
'ninesuperior',
|
|
||||||
'zeroinferior',
|
|
||||||
'oneinferior',
|
|
||||||
'twoinferior',
|
|
||||||
'threeinferior',
|
|
||||||
'fourinferior',
|
|
||||||
'fiveinferior',
|
|
||||||
'sixinferior',
|
|
||||||
'seveninferior',
|
|
||||||
'eightinferior',
|
|
||||||
'nineinferior',
|
|
||||||
'centinferior',
|
|
||||||
'dollarinferior',
|
|
||||||
'periodinferior',
|
|
||||||
'commainferior',
|
|
||||||
'Agravesmall',
|
|
||||||
'Aacutesmall',
|
|
||||||
'Acircumflexsmall',
|
|
||||||
'Atildesmall',
|
|
||||||
'Adieresissmall',
|
|
||||||
'Aringsmall',
|
|
||||||
'AEsmall',
|
|
||||||
'Ccedillasmall',
|
|
||||||
'Egravesmall',
|
|
||||||
'Eacutesmall',
|
|
||||||
'Ecircumflexsmall',
|
|
||||||
'Edieresissmall',
|
|
||||||
'Igravesmall',
|
|
||||||
'Iacutesmall',
|
|
||||||
'Icircumflexsmall',
|
|
||||||
'Idieresissmall',
|
|
||||||
'Ethsmall',
|
|
||||||
'Ntildesmall',
|
|
||||||
'Ogravesmall',
|
|
||||||
'Oacutesmall',
|
|
||||||
'Ocircumflexsmall',
|
|
||||||
'Otildesmall',
|
|
||||||
'Odieresissmall',
|
|
||||||
'OEsmall',
|
|
||||||
'Oslashsmall',
|
|
||||||
'Ugravesmall',
|
|
||||||
'Uacutesmall',
|
|
||||||
'Ucircumflexsmall',
|
|
||||||
'Udieresissmall',
|
|
||||||
'Yacutesmall',
|
|
||||||
'Thornsmall',
|
|
||||||
'Ydieresissmall',
|
|
||||||
'001.000',
|
|
||||||
'001.001',
|
|
||||||
'001.002',
|
|
||||||
'001.003',
|
|
||||||
'Black',
|
|
||||||
'Bold',
|
|
||||||
'Book',
|
|
||||||
'Light',
|
|
||||||
'Medium',
|
|
||||||
'Regular',
|
|
||||||
'Roman',
|
|
||||||
'Semibold'
|
|
||||||
];
|
|
||||||
|
|
||||||
var CFFEncodingMap = {
|
var CFFEncodingMap = {
|
||||||
'0': '-reserved-',
|
'0': '-reserved-',
|
||||||
'1': 'hstem',
|
'1': 'hstem',
|
||||||
|
@ -20,17 +20,27 @@ function readCharset(aStream, aCharstrings) {
|
|||||||
var charset = {};
|
var charset = {};
|
||||||
|
|
||||||
var format = aStream.getByte();
|
var format = aStream.getByte();
|
||||||
|
var count = aCharstrings.length - 1;
|
||||||
if (format == 0) {
|
if (format == 0) {
|
||||||
charset['.notdef'] = readCharstringEncoding(aCharstrings[0]);
|
charset['.notdef'] = readCharstringEncoding(aCharstrings[0]);
|
||||||
|
|
||||||
var count = aCharstrings.length - 1;
|
|
||||||
for (var i = 1; i < count + 1; i++) {
|
for (var i = 1; i < count + 1; i++) {
|
||||||
var sid = aStream.getByte() << 8 | aStream.getByte();
|
var sid = aStream.getByte() << 8 | aStream.getByte();
|
||||||
charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[i]);
|
charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[i]);
|
||||||
//log(CFFStrings[sid] + "::" + charset[CFFStrings[sid]]);
|
//log(CFFStrings[sid] + "::" + charset[CFFStrings[sid]]);
|
||||||
}
|
}
|
||||||
} else if (format == 1) {
|
} else if (format == 1) {
|
||||||
error('Charset Range are not supported');
|
for (var i = 1; i < count + 1; i++) {
|
||||||
|
var first = aStream.getByte();
|
||||||
|
first = (first << 8) | aStream.getByte();
|
||||||
|
var numLeft = aStream.getByte();
|
||||||
|
for (var j = 0; j <= numLeft; j++) {
|
||||||
|
var sid = first++;
|
||||||
|
if (CFFStrings[sid] == 'three')
|
||||||
|
log(aCharstrings[j]);
|
||||||
|
charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
error('Invalid charset format');
|
error('Invalid charset format');
|
||||||
}
|
}
|
||||||
@ -44,6 +54,9 @@ function readCharset(aStream, aCharstrings) {
|
|||||||
* chapter 3.1.
|
* chapter 3.1.
|
||||||
*/
|
*/
|
||||||
function readCharstringEncoding(aString) {
|
function readCharstringEncoding(aString) {
|
||||||
|
if (!aString)
|
||||||
|
return '';
|
||||||
|
|
||||||
var charstringTokens = [];
|
var charstringTokens = [];
|
||||||
|
|
||||||
var count = aString.length;
|
var count = aString.length;
|
||||||
@ -71,9 +84,9 @@ function readCharstringEncoding(aString) {
|
|||||||
} else if (value < 247) {
|
} else if (value < 247) {
|
||||||
token = parseInt(value, 10) - 139;
|
token = parseInt(value, 10) - 139;
|
||||||
} else if (value < 251) {
|
} else if (value < 251) {
|
||||||
token = ((value - 247) * 256) + aString[i++] + 108;
|
token = (value - 247) * 256 + aString[i++] + 108;
|
||||||
} else if (value < 255) {
|
} else if (value < 255) {
|
||||||
token = -((value - 251) * 256) - aString[i++] - 108;
|
token = -(value - 251) * 256 - aString[i++] - 108;
|
||||||
} else {// value == 255
|
} else {// value == 255
|
||||||
token = aString[i++] << 24 | aString[i++] << 16 |
|
token = aString[i++] << 24 | aString[i++] << 16 |
|
||||||
aString[i++] << 8 | aString[i];
|
aString[i++] << 8 | aString[i];
|
||||||
@ -146,9 +159,9 @@ function readFontDictData(aString, aMap) {
|
|||||||
} else if (value <= 246) {
|
} else if (value <= 246) {
|
||||||
token = parseInt(value, 10) - 139;
|
token = parseInt(value, 10) - 139;
|
||||||
} else if (value <= 250) {
|
} else if (value <= 250) {
|
||||||
token = ((value - 247) * 256) + aString[i++] + 108;
|
token = (value - 247) * 256 + aString[i++] + 108;
|
||||||
} else if (value <= 254) {
|
} else if (value <= 254) {
|
||||||
token = -((value - 251) * 256) - aString[i++] - 108;
|
token = -(value - 251) * 256 - aString[i++] - 108;
|
||||||
} else if (value == 255) {
|
} else if (value == 255) {
|
||||||
error('255 is not a valid DICT command');
|
error('255 is not a valid DICT command');
|
||||||
}
|
}
|
||||||
@ -199,7 +212,7 @@ function readFontIndexData(aStream, aIsByte) {
|
|||||||
for (var i = 0; i < count + 1; i++)
|
for (var i = 0; i < count + 1; i++)
|
||||||
offsets.push(getNextOffset());
|
offsets.push(getNextOffset());
|
||||||
|
|
||||||
log('Found ' + count + ' objects at offsets :' +
|
dump('Found ' + count + ' objects at offsets :' +
|
||||||
offsets + ' (offsize: ' + offsize + ')');
|
offsets + ' (offsize: ' + offsize + ')');
|
||||||
|
|
||||||
// Now extract the objects
|
// Now extract the objects
|
||||||
@ -285,23 +298,20 @@ var Type2Parser = function(aFilePath) {
|
|||||||
font.set('hdrSize', aStream.getByte());
|
font.set('hdrSize', aStream.getByte());
|
||||||
font.set('offsize', aStream.getByte());
|
font.set('offsize', aStream.getByte());
|
||||||
|
|
||||||
// Move the cursor after the header
|
|
||||||
aStream.skip(font.get('hdrSize') - aStream.pos);
|
|
||||||
|
|
||||||
// Read the NAME Index
|
// Read the NAME Index
|
||||||
dump('Reading Index: Names');
|
dump('Reading Index: Names');
|
||||||
font.set('Names', readFontIndexData(aStream));
|
font.set('Names', readFontIndexData(aStream));
|
||||||
log('Names: ' + font.get('Names'));
|
dump('Names: ' + font.get('Names'));
|
||||||
|
|
||||||
// Read the Top Dict Index
|
// Read the Top Dict Index
|
||||||
dump('Reading Index: TopDict');
|
dump('Reading Index: TopDict');
|
||||||
var topDict = readFontIndexData(aStream, true);
|
var topDict = readFontIndexData(aStream, true);
|
||||||
log('TopDict: ' + topDict);
|
dump('TopDict: ' + topDict);
|
||||||
|
|
||||||
// Read the String Index
|
// Read the String Index
|
||||||
dump('Reading Index: Strings');
|
dump('Reading Index: Strings');
|
||||||
var strings = readFontIndexData(aStream);
|
var strings = readFontIndexData(aStream);
|
||||||
log('strings: ' + strings);
|
dump('strings: ' + strings);
|
||||||
|
|
||||||
// Fill up the Strings dictionary with the new unique strings
|
// Fill up the Strings dictionary with the new unique strings
|
||||||
for (var i = 0; i < strings.length; i++)
|
for (var i = 0; i < strings.length; i++)
|
||||||
@ -321,7 +331,7 @@ var Type2Parser = function(aFilePath) {
|
|||||||
|
|
||||||
// Reading Private Dict
|
// Reading Private Dict
|
||||||
var priv = font.get('Private');
|
var priv = font.get('Private');
|
||||||
log('Reading Private Dict (offset: ' + priv.offset +
|
dump('Reading Private Dict (offset: ' + priv.offset +
|
||||||
' size: ' + priv.size + ')');
|
' size: ' + priv.size + ')');
|
||||||
aStream.pos = priv.offset;
|
aStream.pos = priv.offset;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<script type="text/javascript" src="../crypto.js"></script>
|
<script type="text/javascript" src="../crypto.js"></script>
|
||||||
<script type="text/javascript" src="../glyphlist.js"></script>
|
<script type="text/javascript" src="../glyphlist.js"></script>
|
||||||
<script type="text/javascript" src="../metrics.js"></script>
|
<script type="text/javascript" src="../metrics.js"></script>
|
||||||
|
<script type="text/javascript" src="../charsets.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user