Merge branch 'master' of https://github.com/andreasgal/pdf.js.git into zoom-bookmark

This commit is contained in:
notmasteryet 2011-09-04 18:46:26 -05:00
commit 7795d3fa4e
2 changed files with 80 additions and 61 deletions

View File

@ -1439,7 +1439,6 @@ var Type1Parser = function() {
var charstring = []; var charstring = [];
var lsb = 0; var lsb = 0;
var width = 0; var width = 0;
var used = false;
var value = ''; var value = '';
var count = array.length; var count = array.length;
@ -1458,7 +1457,7 @@ var Type1Parser = function() {
for (var j = 0; j < argc; j++) for (var j = 0; j < argc; j++)
charstring.push('drop'); charstring.push('drop');
// If the flex mechanishm is not used in a font program, Adobe // If the flex mechanism is not used in a font program, Adobe
// state that that entries 0, 1 and 2 can simply be replace by // state that that entries 0, 1 and 2 can simply be replace by
// {}, which means that we can simply ignore them. // {}, which means that we can simply ignore them.
if (index < 3) { if (index < 3) {
@ -1467,6 +1466,7 @@ var Type1Parser = function() {
// This is the same things about hint replacement, if it is not used // This is the same things about hint replacement, if it is not used
// entry 3 can be replaced by {3} // entry 3 can be replaced by {3}
// TODO support hint replacment
if (index == 3) { if (index == 3) {
charstring.push(3); charstring.push(3);
i++; i++;
@ -1477,7 +1477,7 @@ var Type1Parser = function() {
command = charStringDictionary['12'][escape]; command = charStringDictionary['12'][escape];
} else { } else {
// TODO Clean this code // TODO Clean this code
if (value == 13) { if (value == 13) { //hsbw
if (charstring.length == 2) { if (charstring.length == 2) {
lsb = charstring[0]; lsb = charstring[0];
width = charstring[1]; width = charstring[1];
@ -1509,7 +1509,7 @@ var Type1Parser = function() {
} else if (command == -1) { } else if (command == -1) {
error('Support for Type1 command ' + value + error('Support for Type1 command ' + value +
' (' + escape + ') is not implemented in charstring: ' + ' (' + escape + ') is not implemented in charstring: ' +
charString); charstring);
} }
value = command; value = command;
@ -1535,7 +1535,11 @@ var Type1Parser = function() {
* array extracted from and eexec encrypted block of data * array extracted from and eexec encrypted block of data
*/ */
function readNumberArray(str, index) { function readNumberArray(str, index) {
var start = ++index; var start = index;
while (str[index++] != '[')
start++;
start++;
var count = 0; var count = 0;
while (str[index++] != ']') while (str[index++] != ']')
count++; count++;
@ -1569,7 +1573,9 @@ var Type1Parser = function() {
subrs: [], subrs: [],
charstrings: [], charstrings: [],
properties: { properties: {
'private': {} 'private': {
'lenIV': 4
}
} }
}; };
@ -1592,9 +1598,12 @@ var Type1Parser = function() {
}; };
var c = eexecStr[i]; var c = eexecStr[i];
if ((glyphsSection || subrsSection) && c == 'R') { if ((glyphsSection || subrsSection) &&
var data = eexec.slice(i + 3, i + 3 + length); (token == 'RD' || token == '-|')) {
var encoded = decrypt(data, kCharStringsEncryptionKey, 4); i++;
var data = eexec.slice(i, i + length);
var lenIV = program.properties.private['lenIV'];
var encoded = decrypt(data, kCharStringsEncryptionKey, lenIV);
var str = decodeCharString(encoded); var str = decodeCharString(encoded);
if (glyphsSection) { if (glyphsSection) {
@ -1607,7 +1616,8 @@ var Type1Parser = function() {
} else { } else {
program.subrs.push(str.charstring); program.subrs.push(str.charstring);
} }
i += length + 3; i += length;
token = '';
} else if (c == ' ' || c == '\n') { } else if (c == ' ' || c == '\n') {
length = parseInt(token); length = parseInt(token);
token = ''; token = '';
@ -1624,7 +1634,7 @@ var Type1Parser = function() {
getToken(); // read in 'array' getToken(); // read in 'array'
for (var j = 0; j < num; ++j) { for (var j = 0; j < num; ++j) {
var t = getToken(); // read in 'dup' var t = getToken(); // read in 'dup'
if (t == 'ND') if (t == 'ND' || t == '|-' || t == 'noaccess')
break; break;
var index = parseInt(getToken()); var index = parseInt(getToken());
if (index > j) if (index > j)
@ -1632,10 +1642,13 @@ var Type1Parser = function() {
var length = parseInt(getToken()); var length = parseInt(getToken());
getToken(); // read in 'RD' getToken(); // read in 'RD'
var data = eexec.slice(i + 1, i + 1 + length); var data = eexec.slice(i + 1, i + 1 + length);
var encoded = decrypt(data, kCharStringsEncryptionKey, 4); var lenIV = program.properties.private['lenIV'];
var encoded = decrypt(data, kCharStringsEncryptionKey, lenIV);
var str = decodeCharString(encoded); var str = decodeCharString(encoded);
i = i + 1 + length; i = i + 1 + length;
getToken(); //read in 'NP' t = getToken(); //read in 'NP'
if (t == 'noaccess')
getToken(); //read in 'put'
program.subrs[index] = str.charstring; program.subrs[index] = str.charstring;
} }
break; break;
@ -1646,7 +1659,7 @@ var Type1Parser = function() {
case '/StemSnapH': case '/StemSnapH':
case '/StemSnapV': case '/StemSnapV':
program.properties.private[token.substring(1)] = program.properties.private[token.substring(1)] =
readNumberArray(eexecStr, i + 2); readNumberArray(eexecStr, i + 1);
break; break;
case '/StdHW': case '/StdHW':
case '/StdVW': case '/StdVW':
@ -1654,6 +1667,7 @@ var Type1Parser = function() {
readNumberArray(eexecStr, i + 2)[0]; readNumberArray(eexecStr, i + 2)[0];
break; break;
case '/BlueShift': case '/BlueShift':
case '/lenIV':
case '/BlueFuzz': case '/BlueFuzz':
case '/BlueScale': case '/BlueScale':
case '/LanguageGroup': case '/LanguageGroup':
@ -1821,7 +1835,7 @@ var CFF = function(name, file, properties) {
// Decrypt the data blocks and retrieve it's content // Decrypt the data blocks and retrieve it's content
var eexecBlock = file.getBytes(length2); var eexecBlock = file.getBytes(length2);
var data = type1Parser.extractFontProgram(eexecBlock, properties); var data = type1Parser.extractFontProgram(eexecBlock);
for (var info in data.properties) for (var info in data.properties)
properties[info] = data.properties[info]; properties[info] = data.properties[info];
@ -1929,7 +1943,7 @@ CFF.prototype = {
return type2Charstrings; return type2Charstrings;
}, },
getType2Subrs: function cff_getType2Charstrings(type1Subrs) { getType2Subrs: function cff_getType2Subrs(type1Subrs) {
var bias = 0; var bias = 0;
var count = type1Subrs.length; var count = type1Subrs.length;
if (count < 1240) if (count < 1240)
@ -1987,11 +2001,10 @@ CFF.prototype = {
var cmd = map[command]; var cmd = map[command];
assert(cmd, 'Unknow command: ' + command); assert(cmd, 'Unknow command: ' + command);
if (IsArray(cmd)) { if (IsArray(cmd))
charstring.splice(i++, 1, cmd[0], cmd[1]); charstring.splice(i++, 1, cmd[0], cmd[1]);
} else { else
charstring[i] = cmd; charstring[i] = cmd;
}
} else { } else {
// Type1 charstring use a division for number above 32000 // Type1 charstring use a division for number above 32000
if (command > 32000) { if (command > 32000) {
@ -2110,7 +2123,8 @@ CFF.prototype = {
ExpansionFactor: '\x0c\x18' ExpansionFactor: '\x0c\x18'
}; };
for (var field in fieldMap) { for (var field in fieldMap) {
if (!properties.private.hasOwnProperty(field)) continue; if (!properties.private.hasOwnProperty(field))
continue;
var value = properties.private[field]; var value = properties.private[field];
if (IsArray(value)) { if (IsArray(value)) {

83
pdf.js
View File

@ -1,4 +1,4 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
'use strict'; 'use strict';
@ -18,6 +18,16 @@ function warn(msg) {
log('Warning: ' + msg); log('Warning: ' + msg);
} }
function backtrace() {
var stackStr;
try {
throw new Error();
} catch (e) {
stackStr = e.stack;
}
return stackStr.split('\n').slice(1).join('\n');
}
function error(msg) { function error(msg) {
log(backtrace()); log(backtrace());
throw new Error(msg); throw new Error(msg);
@ -44,16 +54,6 @@ function assertWellFormed(cond, msg) {
malformed(msg); malformed(msg);
} }
function backtrace() {
var stackStr;
try {
throw new Error();
} catch (e) {
stackStr = e.stack;
}
return stackStr.split('\n').slice(1).join('\n');
}
function shadow(obj, prop, value) { function shadow(obj, prop, value) {
try { try {
Object.defineProperty(obj, prop, { value: value, Object.defineProperty(obj, prop, { value: value,
@ -185,7 +185,7 @@ var DecodeStream = (function() {
var buffer2 = new Uint8Array(size); var buffer2 = new Uint8Array(size);
for (var i = 0; i < current; ++i) for (var i = 0; i < current; ++i)
buffer2[i] = buffer[i]; buffer2[i] = buffer[i];
return this.buffer = buffer2; return (this.buffer = buffer2);
}, },
getByte: function decodestream_getByte() { getByte: function decodestream_getByte() {
var pos = this.pos; var pos = this.pos;
@ -197,11 +197,11 @@ var DecodeStream = (function() {
return this.buffer[this.pos++]; return this.buffer[this.pos++];
}, },
getBytes: function decodestream_getBytes(length) { getBytes: function decodestream_getBytes(length) {
var pos = this.pos; var end, pos = this.pos;
if (length) { if (length) {
this.ensureBuffer(pos + length); this.ensureBuffer(pos + length);
var end = pos + length; end = pos + length;
while (!this.eof && this.bufferLength < end) while (!this.eof && this.bufferLength < end)
this.readBlock(); this.readBlock();
@ -213,7 +213,7 @@ var DecodeStream = (function() {
while (!this.eof) while (!this.eof)
this.readBlock(); this.readBlock();
var end = this.bufferLength; end = this.bufferLength;
// checking if bufferLength is still 0 then // checking if bufferLength is still 0 then
// the buffer has to be initialized // the buffer has to be initialized
@ -265,7 +265,7 @@ var FakeStream = (function() {
function constructor(stream) { function constructor(stream) {
this.dict = stream.dict; this.dict = stream.dict;
DecodeStream.call(this); DecodeStream.call(this);
}; }
constructor.prototype = Object.create(DecodeStream.prototype); constructor.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.readBlock = function() { constructor.prototype.readBlock = function() {
@ -532,8 +532,8 @@ var FlateStream = (function() {
constructor.prototype.readBlock = function() { constructor.prototype.readBlock = function() {
function repeat(stream, array, len, offset, what) { function repeat(stream, array, len, offset, what) {
var repeat = stream.getBits(len) + offset; var repeatLength = stream.getBits(len) + offset;
while (repeat-- > 0) while (repeatLength-- > 0)
array[i++] = what; array[i++] = what;
} }
@ -821,8 +821,8 @@ var PredictorStream = (function() {
currentRow[i] = up + c; currentRow[i] = up + c;
else else
currentRow[i] = upLeft + c; currentRow[i] = upLeft + c;
break;
} }
break;
default: default:
error('Unsupported predictor: ' + predictor); error('Unsupported predictor: ' + predictor);
break; break;
@ -1621,6 +1621,7 @@ var CCITTFaxStream = (function() {
this.err = false; this.err = false;
var code1, code2, code3;
if (this.nextLine2D) { if (this.nextLine2D) {
for (var i = 0; codingLine[i] < columns; ++i) for (var i = 0; codingLine[i] < columns; ++i)
refLine[i] = codingLine[i]; refLine[i] = codingLine[i];
@ -1633,7 +1634,7 @@ var CCITTFaxStream = (function() {
blackPixels = 0; blackPixels = 0;
while (codingLine[this.codingPos] < columns) { while (codingLine[this.codingPos] < columns) {
var code1 = this.getTwoDimCode(); code1 = this.getTwoDimCode();
switch (code1) { switch (code1) {
case twoDimPass: case twoDimPass:
this.addPixels(refLine[refPos + 1], blackPixels); this.addPixels(refLine[refPos + 1], blackPixels);
@ -1641,9 +1642,8 @@ var CCITTFaxStream = (function() {
refPos += 2; refPos += 2;
break; break;
case twoDimHoriz: case twoDimHoriz:
var code1 = 0, code2 = 0; code1 = code2 = 0;
if (blackPixels) { if (blackPixels) {
var code3;
do { do {
code1 += (code3 = this.getBlackCode()); code1 += (code3 = this.getBlackCode());
} while (code3 >= 64); } while (code3 >= 64);
@ -1651,7 +1651,6 @@ var CCITTFaxStream = (function() {
code2 += (code3 = this.getWhiteCode()); code2 += (code3 = this.getWhiteCode());
} while (code3 >= 64); } while (code3 >= 64);
} else { } else {
var code3;
do { do {
code1 += (code3 = this.getWhiteCode()); code1 += (code3 = this.getWhiteCode());
} while (code3 >= 64); } while (code3 >= 64);
@ -1831,7 +1830,6 @@ var CCITTFaxStream = (function() {
this.eof = true; this.eof = true;
} }
} else if (this.err && this.eoline) { } else if (this.err && this.eoline) {
var code1;
while (true) { while (true) {
code1 = this.lookBits(13); code1 = this.lookBits(13);
if (code1 == EOF) { if (code1 == EOF) {
@ -2403,7 +2401,7 @@ var Lexer = (function() {
var floating = false; var floating = false;
var str = ch; var str = ch;
var stream = this.stream; var stream = this.stream;
do { for (;;) {
ch = stream.lookChar(); ch = stream.lookChar();
if (ch == '.' && !floating) { if (ch == '.' && !floating) {
str += ch; str += ch;
@ -2421,7 +2419,7 @@ var Lexer = (function() {
break; break;
} }
stream.skip(); stream.skip();
} while (true); }
var value = parseFloat(str); var value = parseFloat(str);
if (isNaN(value)) if (isNaN(value))
error('Invalid floating point number: ' + value); error('Invalid floating point number: ' + value);
@ -2541,7 +2539,7 @@ var Lexer = (function() {
getHexString: function(ch) { getHexString: function(ch) {
var str = ''; var str = '';
var stream = this.stream; var stream = this.stream;
while (1) { for (;;) {
ch = stream.getChar(); ch = stream.getChar();
if (ch == '>') { if (ch == '>') {
break; break;
@ -3378,15 +3376,15 @@ var Page = (function() {
rotatePoint: function(x, y) { rotatePoint: function(x, y) {
var rotate = this.rotate; var rotate = this.rotate;
switch (rotate) { switch (rotate) {
default:
case 0:
return {x: x, y: this.height - y};
case 180: case 180:
return {x: this.width - x, y: y}; return {x: this.width - x, y: y};
case 90: case 90:
return {x: this.width - y, y: this.height - x}; return {x: this.width - y, y: this.height - x};
case 270: case 270:
return {x: y, y: x}; return {x: y, y: x};
case 0:
default:
return {x: x, y: this.height - y};
} }
}, },
getLinks: function() { getLinks: function() {
@ -3548,7 +3546,7 @@ var Catalog = (function() {
} }
}, },
get destinations() { get destinations() {
function fetchDestination(ref) { function fetchDestination(xref, ref) {
var dest = xref.fetchIfRef(ref); var dest = xref.fetchIfRef(ref);
return IsDict(dest) ? dest.get('D') : dest; return IsDict(dest) ? dest.get('D') : dest;
} }
@ -3566,7 +3564,7 @@ var Catalog = (function() {
obj = xref.fetchIfRef(nameDictionaryRef); obj = xref.fetchIfRef(nameDictionaryRef);
obj.forEach(function(key, value) { obj.forEach(function(key, value) {
if (!value) return; if (!value) return;
dests[key] = fetchDestination(value); dests[key] = fetchDestination(xref, value);
}); });
} }
if (nameTreeRef) { if (nameTreeRef) {
@ -3590,7 +3588,7 @@ var Catalog = (function() {
} }
var names = obj.get('Names'); var names = obj.get('Names');
for (i = 0, n = names.length; i < n; i += 2) { for (i = 0, n = names.length; i < n; i += 2) {
dests[names[i]] = fetchDestination(names[i + 1]); dests[names[i]] = fetchDestination(xref, names[i + 1]);
} }
} }
} }
@ -4268,7 +4266,7 @@ var PartialEvaluator = (function() {
} else if (IsName(encoding)) { } else if (IsName(encoding)) {
baseEncoding = Encodings[encoding.name].slice(); baseEncoding = Encodings[encoding.name].slice();
} else { } else {
error("Encoding is not a Name nor a Dict"); error('Encoding is not a Name nor a Dict');
} }
} }
@ -4300,11 +4298,18 @@ var PartialEvaluator = (function() {
var glyphsMap = {}; var glyphsMap = {};
for (var i = firstChar; i <= lastChar; i++) { for (var i = firstChar; i <= lastChar; i++) {
var glyph = diffEncoding[i] || baseEncoding[i]; var glyph = diffEncoding[i] || baseEncoding[i];
if (glyph) if (glyph) {
glyphsMap[glyph] = encodingMap[i] = GlyphsUnicode[glyph] || i; var index = GlyphsUnicode[glyph] || i;
glyphsMap[glyph] = encodingMap[i] = index;
var kCmapGlyphOffset = 0xE000;
if (index <= 0x1f || (index >= 127 && index <= 255))
glyphsMap[glyph] = encodingMap[i] += kCmapGlyphOffset;
}
} }
if (fontType == 'TrueType' && fontDict.has('ToUnicode') && differences) { if (fontType == 'TrueType' && fontDict.has('ToUnicode') &&
differences) {
var cmapObj = xref.fetchIfRef(fontDict.get('ToUnicode')); var cmapObj = xref.fetchIfRef(fontDict.get('ToUnicode'));
if (IsName(cmapObj)) { if (IsName(cmapObj)) {
error('ToUnicode file cmap translation not implemented'); error('ToUnicode file cmap translation not implemented');
@ -4803,8 +4808,8 @@ var CanvasGraphics = (function() {
size = (size <= kRasterizerMin) ? size * kScalePrecision : size; size = (size <= kRasterizerMin) ? size * kScalePrecision : size;
var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') :
: (fontObj.bold ? 'bold' : 'normal'); (fontObj.bold ? 'bold' : 'normal');
var italic = fontObj.italic ? 'italic' : 'normal'; var italic = fontObj.italic ? 'italic' : 'normal';
var rule = italic + ' ' + bold + ' ' + size + 'px "' + name + '"'; var rule = italic + ' ' + bold + ' ' + size + 'px "' + name + '"';