Browse Source

PDF.js version 1.4.179 - See mozilla/pdf.js@8910cea7d66dcb160456886bbd6592817997619a

master v1.4.179
Pdf Bot 9 years ago
parent
commit
62ee8d8d3d
  1. 2
      bower.json
  2. 526
      build/pdf.combined.js
  3. 4
      build/pdf.js
  4. 526
      build/pdf.worker.js
  5. 2
      package.json

2
bower.json

@ -1,6 +1,6 @@
{ {
"name": "pdfjs-dist", "name": "pdfjs-dist",
"version": "1.4.176", "version": "1.4.179",
"main": [ "main": [
"build/pdf.js", "build/pdf.js",
"build/pdf.worker.js" "build/pdf.worker.js"

526
build/pdf.combined.js

@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdfCombined = {}));
// Use strict in our context only - users might not want it // Use strict in our context only - users might not want it
'use strict'; 'use strict';
var pdfjsVersion = '1.4.176'; var pdfjsVersion = '1.4.179';
var pdfjsBuild = '447c48e'; var pdfjsBuild = '8910cea';
var pdfjsFilePath = var pdfjsFilePath =
typeof document !== 'undefined' && document.currentScript ? typeof document !== 'undefined' && document.currentScript ?
@ -29398,6 +29398,7 @@ var shadow = sharedUtil.shadow;
var stringToBytes = sharedUtil.stringToBytes; var stringToBytes = sharedUtil.stringToBytes;
var string32 = sharedUtil.string32; var string32 = sharedUtil.string32;
var warn = sharedUtil.warn; var warn = sharedUtil.warn;
var MissingDataException = sharedUtil.MissingDataException;
var Stream = coreStream.Stream; var Stream = coreStream.Stream;
var Lexer = coreParser.Lexer; var Lexer = coreParser.Lexer;
var getGlyphsUnicode = coreGlyphList.getGlyphsUnicode; var getGlyphsUnicode = coreGlyphList.getGlyphsUnicode;
@ -32981,231 +32982,352 @@ var CFFStandardStrings = [
]; ];
// Type1Font is also a CIDFontType0. // Type1Font is also a CIDFontType0.
var Type1Font = function Type1Font(name, file, properties) { var Type1Font = (function Type1FontClosure() {
// Some bad generators embed pfb file as is, we have to strip 6-byte headers. function findBlock(streamBytes, signature, startIndex) {
// Also, length1 and length2 might be off by 6 bytes as well. var streamBytesLength = streamBytes.length;
// http://www.math.ubc.ca/~cass/piscript/type1.pdf var signatureLength = signature.length;
var PFB_HEADER_SIZE = 6; var scanLength = streamBytesLength - signatureLength;
var headerBlockLength = properties.length1;
var eexecBlockLength = properties.length2; var i = startIndex, j, found = false;
var pfbHeader = file.peekBytes(PFB_HEADER_SIZE); while (i < scanLength) {
var pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01; j = 0;
if (pfbHeaderPresent) { while (j < signatureLength && streamBytes[i + j] === signature[j]) {
file.skip(PFB_HEADER_SIZE); j++;
headerBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | }
(pfbHeader[3] << 8) | pfbHeader[2]; if (j >= signatureLength) { // `signature` found, skip over whitespace.
} i += j;
while (i < streamBytesLength && Lexer.isSpace(streamBytes[i])) {
// Get the data block containing glyphs and subrs informations i++;
var headerBlock = new Stream(file.getBytes(headerBlockLength)); }
var headerBlockParser = new Type1Parser(headerBlock); found = true;
headerBlockParser.extractFontHeader(properties); break;
}
if (pfbHeaderPresent) { i++;
pfbHeader = file.getBytes(PFB_HEADER_SIZE); }
eexecBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | return {
(pfbHeader[3] << 8) | pfbHeader[2]; found: found,
} length: i,
};
// Decrypt the data blocks and retrieve it's content }
var eexecBlock = new Stream(file.getBytes(eexecBlockLength));
var eexecBlockParser = new Type1Parser(eexecBlock, true);
var data = eexecBlockParser.extractFontProgram();
for (var info in data.properties) {
properties[info] = data.properties[info];
}
var charstrings = data.charstrings;
var type2Charstrings = this.getType2Charstrings(charstrings);
var subrs = this.getType2Subrs(data.subrs);
this.charstrings = charstrings;
this.data = this.wrap(name, type2Charstrings, this.charstrings,
subrs, properties);
this.seacs = this.getSeacs(data.charstrings);
};
Type1Font.prototype = { function getHeaderBlock(stream, suggestedLength) {
get numGlyphs() { var EEXEC_SIGNATURE = [0x65, 0x65, 0x78, 0x65, 0x63];
return this.charstrings.length + 1;
},
getCharset: function Type1Font_getCharset() { var streamStartPos = stream.pos; // Save the initial stream position.
var charset = ['.notdef']; var headerBytes, headerBytesLength, block;
var charstrings = this.charstrings; try {
for (var glyphId = 0; glyphId < charstrings.length; glyphId++) { headerBytes = stream.getBytes(suggestedLength);
charset.push(charstrings[glyphId].glyphName); headerBytesLength = headerBytes.length;
} catch (ex) {
if (ex instanceof MissingDataException) {
throw ex;
}
// Ignore errors if the `suggestedLength` is huge enough that a Uint8Array
// cannot hold the result of `getBytes`, and fallback to simply checking
// the entire stream (fixes issue3928.pdf).
} }
return charset;
},
getGlyphMapping: function Type1Font_getGlyphMapping(properties) { if (headerBytesLength === suggestedLength) {
var charstrings = this.charstrings; // Most of the time `suggestedLength` is correct, so to speed things up we
var glyphNames = ['.notdef'], glyphId; // initially only check the last few bytes to see if the header was found.
for (glyphId = 0; glyphId < charstrings.length; glyphId++) { // Otherwise we (potentially) check the entire stream to prevent errors in
glyphNames.push(charstrings[glyphId].glyphName); // `Type1Parser` (fixes issue5686.pdf).
} block = findBlock(headerBytes, EEXEC_SIGNATURE,
var encoding = properties.builtInEncoding; suggestedLength - 2 * EEXEC_SIGNATURE.length);
if (encoding) {
var builtInEncoding = Object.create(null); if (block.found && block.length === suggestedLength) {
for (var charCode in encoding) { return {
glyphId = glyphNames.indexOf(encoding[charCode]); stream: new Stream(headerBytes),
if (glyphId >= 0) { length: suggestedLength,
builtInEncoding[charCode] = glyphId; };
}
} }
} }
warn('Invalid "Length1" property in Type1 font -- trying to recover.');
stream.pos = streamStartPos; // Reset the stream position.
return type1FontGlyphMapping(properties, builtInEncoding, glyphNames); var SCAN_BLOCK_LENGTH = 2048;
}, var actualLength;
while (true) {
var scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
block = findBlock(scanBytes, EEXEC_SIGNATURE, 0);
getSeacs: function Type1Font_getSeacs(charstrings) { if (block.length === 0) {
var i, ii; break;
var seacMap = []; }
for (i = 0, ii = charstrings.length; i < ii; i++) { stream.pos += block.length; // Update the stream position.
var charstring = charstrings[i];
if (charstring.seac) { if (block.found) {
// Offset by 1 for .notdef actualLength = stream.pos - streamStartPos;
seacMap[i + 1] = charstring.seac; break;
} }
} }
return seacMap; stream.pos = streamStartPos; // Reset the stream position.
},
getType2Charstrings: function Type1Font_getType2Charstrings( if (actualLength) {
type1Charstrings) { return {
var type2Charstrings = []; stream: new Stream(stream.getBytes(actualLength)),
for (var i = 0, ii = type1Charstrings.length; i < ii; i++) { length: actualLength,
type2Charstrings.push(type1Charstrings[i].charstring); };
} }
return type2Charstrings; warn('Unable to recover "Length1" property in Type1 font -- using as is.');
}, return {
stream: new Stream(stream.getBytes(suggestedLength)),
length: suggestedLength,
};
}
getType2Subrs: function Type1Font_getType2Subrs(type1Subrs) { function getEexecBlock(stream, suggestedLength) {
var bias = 0; // We should ideally parse the eexec block to ensure that `suggestedLength`
var count = type1Subrs.length; // is correct, so we don't truncate the block data if it's too small.
if (count < 1133) { // However, this would also require checking if the fixed-content portion
bias = 107; // exists (using the 'Length3' property), and ensuring that it's valid.
} else if (count < 33769) { //
bias = 1131; // Given that `suggestedLength` almost always is correct, all the validation
} else { // would require a great deal of unnecessary parsing for most fonts.
bias = 32768; // To save time, we always fetch the entire stream instead, which also avoid
// issues if `suggestedLength` is huge (see comment in `getHeaderBlock`).
//
// NOTE: This means that the function can include the fixed-content portion
// in the returned eexec block. In practice this does *not* seem to matter,
// since `Type1Parser_extractFontProgram` will skip over any non-commands.
var eexecBytes = stream.getBytes();
return {
stream: new Stream(eexecBytes),
length: eexecBytes.length,
};
}
function Type1Font(name, file, properties) {
// Some bad generators embed pfb file as is, we have to strip 6-byte header.
// Also, length1 and length2 might be off by 6 bytes as well.
// http://www.math.ubc.ca/~cass/piscript/type1.pdf
var PFB_HEADER_SIZE = 6;
var headerBlockLength = properties.length1;
var eexecBlockLength = properties.length2;
var pfbHeader = file.peekBytes(PFB_HEADER_SIZE);
var pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01;
if (pfbHeaderPresent) {
file.skip(PFB_HEADER_SIZE);
headerBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) |
(pfbHeader[3] << 8) | pfbHeader[2];
} }
// Add a bunch of empty subrs to deal with the Type2 bias // Get the data block containing glyphs and subrs informations
var type2Subrs = []; var headerBlock = getHeaderBlock(file, headerBlockLength);
var i; headerBlockLength = headerBlock.length;
for (i = 0; i < bias; i++) { var headerBlockParser = new Type1Parser(headerBlock.stream);
type2Subrs.push([0x0B]); headerBlockParser.extractFontHeader(properties);
if (pfbHeaderPresent) {
pfbHeader = file.getBytes(PFB_HEADER_SIZE);
eexecBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) |
(pfbHeader[3] << 8) | pfbHeader[2];
} }
for (i = 0; i < count; i++) { // Decrypt the data blocks and retrieve it's content
type2Subrs.push(type1Subrs[i]); var eexecBlock = getEexecBlock(file, eexecBlockLength);
eexecBlockLength = eexecBlock.length;
var eexecBlockParser = new Type1Parser(eexecBlock.stream, true);
var data = eexecBlockParser.extractFontProgram();
for (var info in data.properties) {
properties[info] = data.properties[info];
} }
return type2Subrs; var charstrings = data.charstrings;
}, var type2Charstrings = this.getType2Charstrings(charstrings);
var subrs = this.getType2Subrs(data.subrs);
wrap: function Type1Font_wrap(name, glyphs, charstrings, subrs, properties) { this.charstrings = charstrings;
var cff = new CFF(); this.data = this.wrap(name, type2Charstrings, this.charstrings,
cff.header = new CFFHeader(1, 0, 4, 4); subrs, properties);
this.seacs = this.getSeacs(data.charstrings);
cff.names = [name]; }
var topDict = new CFFTopDict(); Type1Font.prototype = {
// CFF strings IDs 0...390 are predefined names, so refering get numGlyphs() {
// to entries in our own String INDEX starts at SID 391. return this.charstrings.length + 1;
topDict.setByName('version', 391); },
topDict.setByName('Notice', 392);
topDict.setByName('FullName', 393); getCharset: function Type1Font_getCharset() {
topDict.setByName('FamilyName', 394); var charset = ['.notdef'];
topDict.setByName('Weight', 395); var charstrings = this.charstrings;
topDict.setByName('Encoding', null); // placeholder for (var glyphId = 0; glyphId < charstrings.length; glyphId++) {
topDict.setByName('FontMatrix', properties.fontMatrix); charset.push(charstrings[glyphId].glyphName);
topDict.setByName('FontBBox', properties.bbox); }
topDict.setByName('charset', null); // placeholder return charset;
topDict.setByName('CharStrings', null); // placeholder },
topDict.setByName('Private', null); // placeholder
cff.topDict = topDict; getGlyphMapping: function Type1Font_getGlyphMapping(properties) {
var charstrings = this.charstrings;
var strings = new CFFStrings(); var glyphNames = ['.notdef'], glyphId;
strings.add('Version 0.11'); // Version for (glyphId = 0; glyphId < charstrings.length; glyphId++) {
strings.add('See original notice'); // Notice glyphNames.push(charstrings[glyphId].glyphName);
strings.add(name); // FullName
strings.add(name); // FamilyName
strings.add('Medium'); // Weight
cff.strings = strings;
cff.globalSubrIndex = new CFFIndex();
var count = glyphs.length;
var charsetArray = [0];
var i, ii;
for (i = 0; i < count; i++) {
var index = CFFStandardStrings.indexOf(charstrings[i].glyphName);
// TODO: Insert the string and correctly map it. Previously it was
// thought mapping names that aren't in the standard strings to .notdef
// was fine, however in issue818 when mapping them all to .notdef the
// adieresis glyph no longer worked.
if (index === -1) {
index = 0;
}
charsetArray.push((index >> 8) & 0xff, index & 0xff);
}
cff.charset = new CFFCharset(false, 0, [], charsetArray);
var charStringsIndex = new CFFIndex();
charStringsIndex.add([0x8B, 0x0E]); // .notdef
for (i = 0; i < count; i++) {
charStringsIndex.add(glyphs[i]);
}
cff.charStrings = charStringsIndex;
var privateDict = new CFFPrivateDict();
privateDict.setByName('Subrs', null); // placeholder
var fields = [
'BlueValues',
'OtherBlues',
'FamilyBlues',
'FamilyOtherBlues',
'StemSnapH',
'StemSnapV',
'BlueShift',
'BlueFuzz',
'BlueScale',
'LanguageGroup',
'ExpansionFactor',
'ForceBold',
'StdHW',
'StdVW'
];
for (i = 0, ii = fields.length; i < ii; i++) {
var field = fields[i];
if (!(field in properties.privateData)) {
continue;
} }
var value = properties.privateData[field]; var encoding = properties.builtInEncoding;
if (isArray(value)) { if (encoding) {
// All of the private dictionary array data in CFF must be stored as var builtInEncoding = Object.create(null);
// "delta-encoded" numbers. for (var charCode in encoding) {
for (var j = value.length - 1; j > 0; j--) { glyphId = glyphNames.indexOf(encoding[charCode]);
value[j] -= value[j - 1]; // ... difference from previous value if (glyphId >= 0) {
builtInEncoding[charCode] = glyphId;
}
} }
} }
privateDict.setByName(field, value);
}
cff.topDict.privateDict = privateDict;
var subrIndex = new CFFIndex(); return type1FontGlyphMapping(properties, builtInEncoding, glyphNames);
for (i = 0, ii = subrs.length; i < ii; i++) { },
subrIndex.add(subrs[i]);
getSeacs: function Type1Font_getSeacs(charstrings) {
var i, ii;
var seacMap = [];
for (i = 0, ii = charstrings.length; i < ii; i++) {
var charstring = charstrings[i];
if (charstring.seac) {
// Offset by 1 for .notdef
seacMap[i + 1] = charstring.seac;
}
}
return seacMap;
},
getType2Charstrings: function Type1Font_getType2Charstrings(
type1Charstrings) {
var type2Charstrings = [];
for (var i = 0, ii = type1Charstrings.length; i < ii; i++) {
type2Charstrings.push(type1Charstrings[i].charstring);
}
return type2Charstrings;
},
getType2Subrs: function Type1Font_getType2Subrs(type1Subrs) {
var bias = 0;
var count = type1Subrs.length;
if (count < 1133) {
bias = 107;
} else if (count < 33769) {
bias = 1131;
} else {
bias = 32768;
}
// Add a bunch of empty subrs to deal with the Type2 bias
var type2Subrs = [];
var i;
for (i = 0; i < bias; i++) {
type2Subrs.push([0x0B]);
}
for (i = 0; i < count; i++) {
type2Subrs.push(type1Subrs[i]);
}
return type2Subrs;
},
wrap: function Type1Font_wrap(name, glyphs, charstrings, subrs,
properties) {
var cff = new CFF();
cff.header = new CFFHeader(1, 0, 4, 4);
cff.names = [name];
var topDict = new CFFTopDict();
// CFF strings IDs 0...390 are predefined names, so refering
// to entries in our own String INDEX starts at SID 391.
topDict.setByName('version', 391);
topDict.setByName('Notice', 392);
topDict.setByName('FullName', 393);
topDict.setByName('FamilyName', 394);
topDict.setByName('Weight', 395);
topDict.setByName('Encoding', null); // placeholder
topDict.setByName('FontMatrix', properties.fontMatrix);
topDict.setByName('FontBBox', properties.bbox);
topDict.setByName('charset', null); // placeholder
topDict.setByName('CharStrings', null); // placeholder
topDict.setByName('Private', null); // placeholder
cff.topDict = topDict;
var strings = new CFFStrings();
strings.add('Version 0.11'); // Version
strings.add('See original notice'); // Notice
strings.add(name); // FullName
strings.add(name); // FamilyName
strings.add('Medium'); // Weight
cff.strings = strings;
cff.globalSubrIndex = new CFFIndex();
var count = glyphs.length;
var charsetArray = [0];
var i, ii;
for (i = 0; i < count; i++) {
var index = CFFStandardStrings.indexOf(charstrings[i].glyphName);
// TODO: Insert the string and correctly map it. Previously it was
// thought mapping names that aren't in the standard strings to .notdef
// was fine, however in issue818 when mapping them all to .notdef the
// adieresis glyph no longer worked.
if (index === -1) {
index = 0;
}
charsetArray.push((index >> 8) & 0xff, index & 0xff);
}
cff.charset = new CFFCharset(false, 0, [], charsetArray);
var charStringsIndex = new CFFIndex();
charStringsIndex.add([0x8B, 0x0E]); // .notdef
for (i = 0; i < count; i++) {
charStringsIndex.add(glyphs[i]);
}
cff.charStrings = charStringsIndex;
var privateDict = new CFFPrivateDict();
privateDict.setByName('Subrs', null); // placeholder
var fields = [
'BlueValues',
'OtherBlues',
'FamilyBlues',
'FamilyOtherBlues',
'StemSnapH',
'StemSnapV',
'BlueShift',
'BlueFuzz',
'BlueScale',
'LanguageGroup',
'ExpansionFactor',
'ForceBold',
'StdHW',
'StdVW'
];
for (i = 0, ii = fields.length; i < ii; i++) {
var field = fields[i];
if (!(field in properties.privateData)) {
continue;
}
var value = properties.privateData[field];
if (isArray(value)) {
// All of the private dictionary array data in CFF must be stored as
// "delta-encoded" numbers.
for (var j = value.length - 1; j > 0; j--) {
value[j] -= value[j - 1]; // ... difference from previous value
}
}
privateDict.setByName(field, value);
}
cff.topDict.privateDict = privateDict;
var subrIndex = new CFFIndex();
for (i = 0, ii = subrs.length; i < ii; i++) {
subrIndex.add(subrs[i]);
}
privateDict.subrsIndex = subrIndex;
var compiler = new CFFCompiler(cff);
return compiler.compile();
} }
privateDict.subrsIndex = subrIndex; };
var compiler = new CFFCompiler(cff); return Type1Font;
return compiler.compile(); })();
}
};
var CFFFont = (function CFFFontClosure() { var CFFFont = (function CFFFontClosure() {
function CFFFont(file, properties) { function CFFFont(file, properties) {
@ -46977,6 +47099,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
var length1 = fontFile.dict.get('Length1'); var length1 = fontFile.dict.get('Length1');
var length2 = fontFile.dict.get('Length2'); var length2 = fontFile.dict.get('Length2');
var length3 = fontFile.dict.get('Length3');
} }
} }
@ -46987,6 +47110,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
file: fontFile, file: fontFile,
length1: length1, length1: length1,
length2: length2, length2: length2,
length3: length3,
loadedName: baseDict.loadedName, loadedName: baseDict.loadedName,
composite: composite, composite: composite,
wideChars: composite, wideChars: composite,

4
build/pdf.js

@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdf = {}));
// Use strict in our context only - users might not want it // Use strict in our context only - users might not want it
'use strict'; 'use strict';
var pdfjsVersion = '1.4.176'; var pdfjsVersion = '1.4.179';
var pdfjsBuild = '447c48e'; var pdfjsBuild = '8910cea';
var pdfjsFilePath = var pdfjsFilePath =
typeof document !== 'undefined' && document.currentScript ? typeof document !== 'undefined' && document.currentScript ?

526
build/pdf.worker.js vendored

@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdfWorker = {}));
// Use strict in our context only - users might not want it // Use strict in our context only - users might not want it
'use strict'; 'use strict';
var pdfjsVersion = '1.4.176'; var pdfjsVersion = '1.4.179';
var pdfjsBuild = '447c48e'; var pdfjsBuild = '8910cea';
var pdfjsFilePath = var pdfjsFilePath =
typeof document !== 'undefined' && document.currentScript ? typeof document !== 'undefined' && document.currentScript ?
@ -25495,6 +25495,7 @@ var shadow = sharedUtil.shadow;
var stringToBytes = sharedUtil.stringToBytes; var stringToBytes = sharedUtil.stringToBytes;
var string32 = sharedUtil.string32; var string32 = sharedUtil.string32;
var warn = sharedUtil.warn; var warn = sharedUtil.warn;
var MissingDataException = sharedUtil.MissingDataException;
var Stream = coreStream.Stream; var Stream = coreStream.Stream;
var Lexer = coreParser.Lexer; var Lexer = coreParser.Lexer;
var getGlyphsUnicode = coreGlyphList.getGlyphsUnicode; var getGlyphsUnicode = coreGlyphList.getGlyphsUnicode;
@ -29078,231 +29079,352 @@ var CFFStandardStrings = [
]; ];
// Type1Font is also a CIDFontType0. // Type1Font is also a CIDFontType0.
var Type1Font = function Type1Font(name, file, properties) { var Type1Font = (function Type1FontClosure() {
// Some bad generators embed pfb file as is, we have to strip 6-byte headers. function findBlock(streamBytes, signature, startIndex) {
// Also, length1 and length2 might be off by 6 bytes as well. var streamBytesLength = streamBytes.length;
// http://www.math.ubc.ca/~cass/piscript/type1.pdf var signatureLength = signature.length;
var PFB_HEADER_SIZE = 6; var scanLength = streamBytesLength - signatureLength;
var headerBlockLength = properties.length1;
var eexecBlockLength = properties.length2; var i = startIndex, j, found = false;
var pfbHeader = file.peekBytes(PFB_HEADER_SIZE); while (i < scanLength) {
var pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01; j = 0;
if (pfbHeaderPresent) { while (j < signatureLength && streamBytes[i + j] === signature[j]) {
file.skip(PFB_HEADER_SIZE); j++;
headerBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | }
(pfbHeader[3] << 8) | pfbHeader[2]; if (j >= signatureLength) { // `signature` found, skip over whitespace.
} i += j;
while (i < streamBytesLength && Lexer.isSpace(streamBytes[i])) {
// Get the data block containing glyphs and subrs informations i++;
var headerBlock = new Stream(file.getBytes(headerBlockLength)); }
var headerBlockParser = new Type1Parser(headerBlock); found = true;
headerBlockParser.extractFontHeader(properties); break;
}
if (pfbHeaderPresent) { i++;
pfbHeader = file.getBytes(PFB_HEADER_SIZE); }
eexecBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | return {
(pfbHeader[3] << 8) | pfbHeader[2]; found: found,
} length: i,
};
// Decrypt the data blocks and retrieve it's content }
var eexecBlock = new Stream(file.getBytes(eexecBlockLength));
var eexecBlockParser = new Type1Parser(eexecBlock, true);
var data = eexecBlockParser.extractFontProgram();
for (var info in data.properties) {
properties[info] = data.properties[info];
}
var charstrings = data.charstrings;
var type2Charstrings = this.getType2Charstrings(charstrings);
var subrs = this.getType2Subrs(data.subrs);
this.charstrings = charstrings;
this.data = this.wrap(name, type2Charstrings, this.charstrings,
subrs, properties);
this.seacs = this.getSeacs(data.charstrings);
};
Type1Font.prototype = { function getHeaderBlock(stream, suggestedLength) {
get numGlyphs() { var EEXEC_SIGNATURE = [0x65, 0x65, 0x78, 0x65, 0x63];
return this.charstrings.length + 1;
},
getCharset: function Type1Font_getCharset() { var streamStartPos = stream.pos; // Save the initial stream position.
var charset = ['.notdef']; var headerBytes, headerBytesLength, block;
var charstrings = this.charstrings; try {
for (var glyphId = 0; glyphId < charstrings.length; glyphId++) { headerBytes = stream.getBytes(suggestedLength);
charset.push(charstrings[glyphId].glyphName); headerBytesLength = headerBytes.length;
} catch (ex) {
if (ex instanceof MissingDataException) {
throw ex;
}
// Ignore errors if the `suggestedLength` is huge enough that a Uint8Array
// cannot hold the result of `getBytes`, and fallback to simply checking
// the entire stream (fixes issue3928.pdf).
} }
return charset;
},
getGlyphMapping: function Type1Font_getGlyphMapping(properties) { if (headerBytesLength === suggestedLength) {
var charstrings = this.charstrings; // Most of the time `suggestedLength` is correct, so to speed things up we
var glyphNames = ['.notdef'], glyphId; // initially only check the last few bytes to see if the header was found.
for (glyphId = 0; glyphId < charstrings.length; glyphId++) { // Otherwise we (potentially) check the entire stream to prevent errors in
glyphNames.push(charstrings[glyphId].glyphName); // `Type1Parser` (fixes issue5686.pdf).
} block = findBlock(headerBytes, EEXEC_SIGNATURE,
var encoding = properties.builtInEncoding; suggestedLength - 2 * EEXEC_SIGNATURE.length);
if (encoding) {
var builtInEncoding = Object.create(null); if (block.found && block.length === suggestedLength) {
for (var charCode in encoding) { return {
glyphId = glyphNames.indexOf(encoding[charCode]); stream: new Stream(headerBytes),
if (glyphId >= 0) { length: suggestedLength,
builtInEncoding[charCode] = glyphId; };
}
} }
} }
warn('Invalid "Length1" property in Type1 font -- trying to recover.');
stream.pos = streamStartPos; // Reset the stream position.
return type1FontGlyphMapping(properties, builtInEncoding, glyphNames); var SCAN_BLOCK_LENGTH = 2048;
}, var actualLength;
while (true) {
var scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH);
block = findBlock(scanBytes, EEXEC_SIGNATURE, 0);
getSeacs: function Type1Font_getSeacs(charstrings) { if (block.length === 0) {
var i, ii; break;
var seacMap = []; }
for (i = 0, ii = charstrings.length; i < ii; i++) { stream.pos += block.length; // Update the stream position.
var charstring = charstrings[i];
if (charstring.seac) { if (block.found) {
// Offset by 1 for .notdef actualLength = stream.pos - streamStartPos;
seacMap[i + 1] = charstring.seac; break;
} }
} }
return seacMap; stream.pos = streamStartPos; // Reset the stream position.
},
getType2Charstrings: function Type1Font_getType2Charstrings( if (actualLength) {
type1Charstrings) { return {
var type2Charstrings = []; stream: new Stream(stream.getBytes(actualLength)),
for (var i = 0, ii = type1Charstrings.length; i < ii; i++) { length: actualLength,
type2Charstrings.push(type1Charstrings[i].charstring); };
} }
return type2Charstrings; warn('Unable to recover "Length1" property in Type1 font -- using as is.');
}, return {
stream: new Stream(stream.getBytes(suggestedLength)),
length: suggestedLength,
};
}
getType2Subrs: function Type1Font_getType2Subrs(type1Subrs) { function getEexecBlock(stream, suggestedLength) {
var bias = 0; // We should ideally parse the eexec block to ensure that `suggestedLength`
var count = type1Subrs.length; // is correct, so we don't truncate the block data if it's too small.
if (count < 1133) { // However, this would also require checking if the fixed-content portion
bias = 107; // exists (using the 'Length3' property), and ensuring that it's valid.
} else if (count < 33769) { //
bias = 1131; // Given that `suggestedLength` almost always is correct, all the validation
} else { // would require a great deal of unnecessary parsing for most fonts.
bias = 32768; // To save time, we always fetch the entire stream instead, which also avoid
// issues if `suggestedLength` is huge (see comment in `getHeaderBlock`).
//
// NOTE: This means that the function can include the fixed-content portion
// in the returned eexec block. In practice this does *not* seem to matter,
// since `Type1Parser_extractFontProgram` will skip over any non-commands.
var eexecBytes = stream.getBytes();
return {
stream: new Stream(eexecBytes),
length: eexecBytes.length,
};
}
function Type1Font(name, file, properties) {
// Some bad generators embed pfb file as is, we have to strip 6-byte header.
// Also, length1 and length2 might be off by 6 bytes as well.
// http://www.math.ubc.ca/~cass/piscript/type1.pdf
var PFB_HEADER_SIZE = 6;
var headerBlockLength = properties.length1;
var eexecBlockLength = properties.length2;
var pfbHeader = file.peekBytes(PFB_HEADER_SIZE);
var pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01;
if (pfbHeaderPresent) {
file.skip(PFB_HEADER_SIZE);
headerBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) |
(pfbHeader[3] << 8) | pfbHeader[2];
} }
// Add a bunch of empty subrs to deal with the Type2 bias // Get the data block containing glyphs and subrs informations
var type2Subrs = []; var headerBlock = getHeaderBlock(file, headerBlockLength);
var i; headerBlockLength = headerBlock.length;
for (i = 0; i < bias; i++) { var headerBlockParser = new Type1Parser(headerBlock.stream);
type2Subrs.push([0x0B]); headerBlockParser.extractFontHeader(properties);
if (pfbHeaderPresent) {
pfbHeader = file.getBytes(PFB_HEADER_SIZE);
eexecBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) |
(pfbHeader[3] << 8) | pfbHeader[2];
} }
for (i = 0; i < count; i++) { // Decrypt the data blocks and retrieve it's content
type2Subrs.push(type1Subrs[i]); var eexecBlock = getEexecBlock(file, eexecBlockLength);
eexecBlockLength = eexecBlock.length;
var eexecBlockParser = new Type1Parser(eexecBlock.stream, true);
var data = eexecBlockParser.extractFontProgram();
for (var info in data.properties) {
properties[info] = data.properties[info];
} }
return type2Subrs; var charstrings = data.charstrings;
}, var type2Charstrings = this.getType2Charstrings(charstrings);
var subrs = this.getType2Subrs(data.subrs);
wrap: function Type1Font_wrap(name, glyphs, charstrings, subrs, properties) { this.charstrings = charstrings;
var cff = new CFF(); this.data = this.wrap(name, type2Charstrings, this.charstrings,
cff.header = new CFFHeader(1, 0, 4, 4); subrs, properties);
this.seacs = this.getSeacs(data.charstrings);
cff.names = [name]; }
var topDict = new CFFTopDict(); Type1Font.prototype = {
// CFF strings IDs 0...390 are predefined names, so refering get numGlyphs() {
// to entries in our own String INDEX starts at SID 391. return this.charstrings.length + 1;
topDict.setByName('version', 391); },
topDict.setByName('Notice', 392);
topDict.setByName('FullName', 393); getCharset: function Type1Font_getCharset() {
topDict.setByName('FamilyName', 394); var charset = ['.notdef'];
topDict.setByName('Weight', 395); var charstrings = this.charstrings;
topDict.setByName('Encoding', null); // placeholder for (var glyphId = 0; glyphId < charstrings.length; glyphId++) {
topDict.setByName('FontMatrix', properties.fontMatrix); charset.push(charstrings[glyphId].glyphName);
topDict.setByName('FontBBox', properties.bbox); }
topDict.setByName('charset', null); // placeholder return charset;
topDict.setByName('CharStrings', null); // placeholder },
topDict.setByName('Private', null); // placeholder
cff.topDict = topDict; getGlyphMapping: function Type1Font_getGlyphMapping(properties) {
var charstrings = this.charstrings;
var strings = new CFFStrings(); var glyphNames = ['.notdef'], glyphId;
strings.add('Version 0.11'); // Version for (glyphId = 0; glyphId < charstrings.length; glyphId++) {
strings.add('See original notice'); // Notice glyphNames.push(charstrings[glyphId].glyphName);
strings.add(name); // FullName
strings.add(name); // FamilyName
strings.add('Medium'); // Weight
cff.strings = strings;
cff.globalSubrIndex = new CFFIndex();
var count = glyphs.length;
var charsetArray = [0];
var i, ii;
for (i = 0; i < count; i++) {
var index = CFFStandardStrings.indexOf(charstrings[i].glyphName);
// TODO: Insert the string and correctly map it. Previously it was
// thought mapping names that aren't in the standard strings to .notdef
// was fine, however in issue818 when mapping them all to .notdef the
// adieresis glyph no longer worked.
if (index === -1) {
index = 0;
}
charsetArray.push((index >> 8) & 0xff, index & 0xff);
}
cff.charset = new CFFCharset(false, 0, [], charsetArray);
var charStringsIndex = new CFFIndex();
charStringsIndex.add([0x8B, 0x0E]); // .notdef
for (i = 0; i < count; i++) {
charStringsIndex.add(glyphs[i]);
}
cff.charStrings = charStringsIndex;
var privateDict = new CFFPrivateDict();
privateDict.setByName('Subrs', null); // placeholder
var fields = [
'BlueValues',
'OtherBlues',
'FamilyBlues',
'FamilyOtherBlues',
'StemSnapH',
'StemSnapV',
'BlueShift',
'BlueFuzz',
'BlueScale',
'LanguageGroup',
'ExpansionFactor',
'ForceBold',
'StdHW',
'StdVW'
];
for (i = 0, ii = fields.length; i < ii; i++) {
var field = fields[i];
if (!(field in properties.privateData)) {
continue;
} }
var value = properties.privateData[field]; var encoding = properties.builtInEncoding;
if (isArray(value)) { if (encoding) {
// All of the private dictionary array data in CFF must be stored as var builtInEncoding = Object.create(null);
// "delta-encoded" numbers. for (var charCode in encoding) {
for (var j = value.length - 1; j > 0; j--) { glyphId = glyphNames.indexOf(encoding[charCode]);
value[j] -= value[j - 1]; // ... difference from previous value if (glyphId >= 0) {
builtInEncoding[charCode] = glyphId;
}
} }
} }
privateDict.setByName(field, value);
}
cff.topDict.privateDict = privateDict;
var subrIndex = new CFFIndex(); return type1FontGlyphMapping(properties, builtInEncoding, glyphNames);
for (i = 0, ii = subrs.length; i < ii; i++) { },
subrIndex.add(subrs[i]);
getSeacs: function Type1Font_getSeacs(charstrings) {
var i, ii;
var seacMap = [];
for (i = 0, ii = charstrings.length; i < ii; i++) {
var charstring = charstrings[i];
if (charstring.seac) {
// Offset by 1 for .notdef
seacMap[i + 1] = charstring.seac;
}
}
return seacMap;
},
getType2Charstrings: function Type1Font_getType2Charstrings(
type1Charstrings) {
var type2Charstrings = [];
for (var i = 0, ii = type1Charstrings.length; i < ii; i++) {
type2Charstrings.push(type1Charstrings[i].charstring);
}
return type2Charstrings;
},
getType2Subrs: function Type1Font_getType2Subrs(type1Subrs) {
var bias = 0;
var count = type1Subrs.length;
if (count < 1133) {
bias = 107;
} else if (count < 33769) {
bias = 1131;
} else {
bias = 32768;
}
// Add a bunch of empty subrs to deal with the Type2 bias
var type2Subrs = [];
var i;
for (i = 0; i < bias; i++) {
type2Subrs.push([0x0B]);
}
for (i = 0; i < count; i++) {
type2Subrs.push(type1Subrs[i]);
}
return type2Subrs;
},
wrap: function Type1Font_wrap(name, glyphs, charstrings, subrs,
properties) {
var cff = new CFF();
cff.header = new CFFHeader(1, 0, 4, 4);
cff.names = [name];
var topDict = new CFFTopDict();
// CFF strings IDs 0...390 are predefined names, so refering
// to entries in our own String INDEX starts at SID 391.
topDict.setByName('version', 391);
topDict.setByName('Notice', 392);
topDict.setByName('FullName', 393);
topDict.setByName('FamilyName', 394);
topDict.setByName('Weight', 395);
topDict.setByName('Encoding', null); // placeholder
topDict.setByName('FontMatrix', properties.fontMatrix);
topDict.setByName('FontBBox', properties.bbox);
topDict.setByName('charset', null); // placeholder
topDict.setByName('CharStrings', null); // placeholder
topDict.setByName('Private', null); // placeholder
cff.topDict = topDict;
var strings = new CFFStrings();
strings.add('Version 0.11'); // Version
strings.add('See original notice'); // Notice
strings.add(name); // FullName
strings.add(name); // FamilyName
strings.add('Medium'); // Weight
cff.strings = strings;
cff.globalSubrIndex = new CFFIndex();
var count = glyphs.length;
var charsetArray = [0];
var i, ii;
for (i = 0; i < count; i++) {
var index = CFFStandardStrings.indexOf(charstrings[i].glyphName);
// TODO: Insert the string and correctly map it. Previously it was
// thought mapping names that aren't in the standard strings to .notdef
// was fine, however in issue818 when mapping them all to .notdef the
// adieresis glyph no longer worked.
if (index === -1) {
index = 0;
}
charsetArray.push((index >> 8) & 0xff, index & 0xff);
}
cff.charset = new CFFCharset(false, 0, [], charsetArray);
var charStringsIndex = new CFFIndex();
charStringsIndex.add([0x8B, 0x0E]); // .notdef
for (i = 0; i < count; i++) {
charStringsIndex.add(glyphs[i]);
}
cff.charStrings = charStringsIndex;
var privateDict = new CFFPrivateDict();
privateDict.setByName('Subrs', null); // placeholder
var fields = [
'BlueValues',
'OtherBlues',
'FamilyBlues',
'FamilyOtherBlues',
'StemSnapH',
'StemSnapV',
'BlueShift',
'BlueFuzz',
'BlueScale',
'LanguageGroup',
'ExpansionFactor',
'ForceBold',
'StdHW',
'StdVW'
];
for (i = 0, ii = fields.length; i < ii; i++) {
var field = fields[i];
if (!(field in properties.privateData)) {
continue;
}
var value = properties.privateData[field];
if (isArray(value)) {
// All of the private dictionary array data in CFF must be stored as
// "delta-encoded" numbers.
for (var j = value.length - 1; j > 0; j--) {
value[j] -= value[j - 1]; // ... difference from previous value
}
}
privateDict.setByName(field, value);
}
cff.topDict.privateDict = privateDict;
var subrIndex = new CFFIndex();
for (i = 0, ii = subrs.length; i < ii; i++) {
subrIndex.add(subrs[i]);
}
privateDict.subrsIndex = subrIndex;
var compiler = new CFFCompiler(cff);
return compiler.compile();
} }
privateDict.subrsIndex = subrIndex; };
var compiler = new CFFCompiler(cff); return Type1Font;
return compiler.compile(); })();
}
};
var CFFFont = (function CFFFontClosure() { var CFFFont = (function CFFFontClosure() {
function CFFFont(file, properties) { function CFFFont(file, properties) {
@ -38810,6 +38932,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
} }
var length1 = fontFile.dict.get('Length1'); var length1 = fontFile.dict.get('Length1');
var length2 = fontFile.dict.get('Length2'); var length2 = fontFile.dict.get('Length2');
var length3 = fontFile.dict.get('Length3');
} }
} }
@ -38820,6 +38943,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
file: fontFile, file: fontFile,
length1: length1, length1: length1,
length2: length2, length2: length2,
length3: length3,
loadedName: baseDict.loadedName, loadedName: baseDict.loadedName,
composite: composite, composite: composite,
wideChars: composite, wideChars: composite,

2
package.json

@ -1,6 +1,6 @@
{ {
"name": "pdfjs-dist", "name": "pdfjs-dist",
"version": "1.4.176", "version": "1.4.179",
"main": "build/pdf.js", "main": "build/pdf.js",
"description": "Generic build of Mozilla's PDF.js library.", "description": "Generic build of Mozilla's PDF.js library.",
"keywords": [ "keywords": [

Loading…
Cancel
Save