1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-26 10:08:06 +02:00

Merge branch 'master' into faxstream

This commit is contained in:
sbarman 2011-06-24 21:05:59 -07:00
commit 2d88566163
13 changed files with 672 additions and 424 deletions

184
pdf.js
View file

@ -56,6 +56,14 @@ function bytesToString(bytes) {
return str;
}
function stringToBytes(str) {
var length = str.length;
var bytes = new Uint8Array(length);
for (var n = 0; n < length; ++n)
bytes[n] = str.charCodeAt(n) & 0xFF;
return bytes;
}
var Stream = (function() {
function constructor(arrayBuffer, start, length, dict) {
this.bytes = new Uint8Array(arrayBuffer);
@ -71,14 +79,14 @@ var Stream = (function() {
get length() {
return this.end - this.start;
},
getByte: function() {
getByte: function stream_getByte() {
if (this.pos >= this.end)
return;
return null;
return this.bytes[this.pos++];
},
// returns subarray of original buffer
// should only be read
getBytes: function(length) {
getBytes: function stream_getBytes(length) {
var bytes = this.bytes;
var pos = this.pos;
var strEnd = this.end;
@ -93,28 +101,28 @@ var Stream = (function() {
this.pos = end;
return bytes.subarray(pos, end);
},
lookChar: function() {
lookChar: function stream_lookChar() {
if (this.pos >= this.end)
return;
return null;
return String.fromCharCode(this.bytes[this.pos]);
},
getChar: function() {
getChar: function stream_getChar() {
if (this.pos >= this.end)
return;
return null;
return String.fromCharCode(this.bytes[this.pos++]);
},
skip: function(n) {
skip: function stream_skip(n) {
if (!n)
n = 1;
this.pos += n;
},
reset: function() {
reset: function stream_reset() {
this.pos = this.start;
},
moveStart: function() {
moveStart: function stream_moveStart() {
this.start = this.pos;
},
makeSubStream: function(start, length, dict) {
makeSubStream: function stream_makeSubstream(start, length, dict) {
return new Stream(this.bytes.buffer, start, length, dict);
}
};
@ -146,7 +154,7 @@ var DecodeStream = (function() {
}
constructor.prototype = {
ensureBuffer: function(requested) {
ensureBuffer: function decodestream_ensureBuffer(requested) {
var buffer = this.buffer;
var current = buffer ? buffer.byteLength : 0;
if (requested < current)
@ -159,16 +167,16 @@ var DecodeStream = (function() {
buffer2[i] = buffer[i];
return this.buffer = buffer2;
},
getByte: function() {
getByte: function decodestream_getByte() {
var pos = this.pos;
while (this.bufferLength <= pos) {
if (this.eof)
return;
return null;
this.readBlock();
}
return this.buffer[this.pos++];
},
getBytes: function(length) {
getBytes: function decodestream_getBytes(length) {
var pos = this.pos;
if (length) {
@ -191,25 +199,25 @@ var DecodeStream = (function() {
this.pos = end;
return this.buffer.subarray(pos, end)
},
lookChar: function() {
lookChar: function decodestream_lookChar() {
var pos = this.pos;
while (this.bufferLength <= pos) {
if (this.eof)
return;
return null;
this.readBlock();
}
return String.fromCharCode(this.buffer[this.pos]);
},
getChar: function() {
getChar: function decodestream_getChar() {
var pos = this.pos;
while (this.bufferLength <= pos) {
if (this.eof)
return;
return null;
this.readBlock();
}
return String.fromCharCode(this.buffer[this.pos++]);
},
skip: function(n) {
skip: function decodestream_skip(n) {
if (!n)
n = 1;
this.pos += n;
@ -635,6 +643,7 @@ var PredictorStream = (function() {
var rowBytes = this.rowBytes = (columns * colors * bits + 7) >> 3;
DecodeStream.call(this);
return this;
}
constructor.prototype = Object.create(DecodeStream.prototype);
@ -707,7 +716,7 @@ var PredictorStream = (function() {
var rawBytes = this.stream.getBytes(rowBytes);
var bufferLength = this.bufferLength;
var buffer = this.ensureBuffer(bufferLength + pixBytes);
var buffer = this.ensureBuffer(bufferLength + rowBytes);
var currentRow = buffer.subarray(bufferLength, bufferLength + rowBytes);
var prevRow = buffer.subarray(bufferLength - rowBytes, bufferLength);
@ -799,11 +808,34 @@ var JpegStream = (function() {
return constructor;
})();
var DecryptStream = (function() {
function constructor(str, fileKey, encAlgorithm, keyLength) {
TODO("decrypt stream is not implemented");
function constructor(str, decrypt) {
this.str = str;
this.dict = str.dict;
this.decrypt = decrypt;
DecodeStream.call(this);
}
constructor.prototype = Stream.prototype;
const chunkSize = 512;
constructor.prototype = Object.create(DecodeStream.prototype);
constructor.prototype.readBlock = function() {
var chunk = this.str.getBytes(chunkSize);
if (!chunk || chunk.length == 0) {
this.eof = true;
return;
}
var decrypt = this.decrypt;
chunk = decrypt(chunk);
var bufferLength = this.bufferLength;
var i, n = chunk.length;
var buffer = this.ensureBuffer(bufferLength + n);
for (i = 0; i < n; i++)
buffer[bufferLength++] = chunk[i];
this.bufferLength = bufferLength;
this.eof = n < chunkSize;
};
return constructor;
})();
@ -1883,7 +1915,9 @@ var Dict = (function() {
constructor.prototype = {
get: function(key) {
return this.map[key];
if (key in this.map)
return this.map[key];
return null;
},
get2: function(key1, key2) {
return this.get(key1) || this.get(key2);
@ -1954,7 +1988,7 @@ function IsArray(v) {
}
function IsStream(v) {
return typeof v == "object" && "getChar" in v;
return typeof v == "object" && v != null && ("getChar" in v);
}
function IsRef(v) {
@ -2023,10 +2057,10 @@ var Lexer = (function() {
function ToHexDigit(ch) {
if (ch >= "0" && ch <= "9")
return ch - "0";
ch = ch.toLowerCase();
if (ch >= "a" && ch <= "f")
return ch - "a";
return ch.charCodeAt(0) - 48;
ch = ch.toUpperCase();
if (ch >= "A" && ch <= "F")
return ch.charCodeAt(0) - 55;
return -1;
}
@ -2320,7 +2354,7 @@ var Parser = (function() {
// don't buffer inline image data
this.buf2 = (this.inlineImg > 0) ? null : this.lexer.getObj();
},
getObj: function() {
getObj: function(cipherTransform) {
// refill buffer after inline image data
if (this.inlineImg == 2)
this.refill();
@ -2346,7 +2380,7 @@ var Parser = (function() {
this.shift();
if (IsEOF(this.buf1))
break;
dict.set(key, this.getObj());
dict.set(key, this.getObj(cipherTransform));
}
}
if (IsEOF(this.buf1))
@ -2355,7 +2389,7 @@ var Parser = (function() {
// stream objects are not allowed inside content streams or
// object streams
if (this.allowStreams && IsCmd(this.buf2, "stream")) {
return this.makeStream(dict);
return this.makeStream(dict, cipherTransform);
} else {
this.shift();
}
@ -2374,17 +2408,8 @@ var Parser = (function() {
} else if (IsString(this.buf1)) { // string
var str = this.buf1;
this.shift();
if (this.fileKey) {
var decrypt = new DecryptStream(new StringStream(str),
this.fileKey,
this.encAlgorithm,
this.keyLength);
var str = "";
var pos = decrypt.pos;
var length = decrypt.length;
while (pos++ > length)
str += decrypt.getChar();
}
if (cipherTransform)
str = cipherTransform.decryptString(str);
return str;
}
@ -2393,7 +2418,7 @@ var Parser = (function() {
this.shift();
return obj;
},
makeStream: function(dict) {
makeStream: function(dict, cipherTransform) {
var lexer = this.lexer;
var stream = lexer.stream;
@ -2420,12 +2445,8 @@ var Parser = (function() {
this.shift();
stream = stream.makeSubStream(pos, length, dict);
if (this.fileKey) {
stream = new DecryptStream(stream,
this.fileKey,
this.encAlgorithm,
this.keyLength);
}
if (cipherTransform)
stream = cipherTransform.createStream(stream);
stream = this.filter(stream, dict, length);
stream.parameters = dict;
return stream;
@ -2559,16 +2580,22 @@ var XRef = (function() {
this.xrefstms = {};
var trailerDict = this.readXRef(startXRef);
// prepare the XRef cache
this.cache = [];
var encrypt = trailerDict.get("Encrypt");
if (encrypt) {
var fileId = trailerDict.get("ID");
this.encrypt = new CipherTransformFactory(this.fetch(encrypt), fileId[0] /*, password */);
}
// get the root dictionary (catalog) object
if (!IsRef(this.root = trailerDict.get("Root")))
error("Invalid root reference");
// prepare the XRef cache
this.cache = [];
}
constructor.prototype = {
readXRefTable: function(parser) {
readXRefTable: function readXRefTable(parser) {
var obj;
while (true) {
if (IsCmd(obj = parser.getObj(), "trailer"))
@ -2639,7 +2666,7 @@ var XRef = (function() {
return dict;
},
readXRefStream: function(stream) {
readXRefStream: function readXRefStream(stream) {
var streamParameters = stream.parameters;
var length = streamParameters.get("Length");
var byteWidths = streamParameters.get("W");
@ -2691,7 +2718,7 @@ var XRef = (function() {
this.readXRef(prev);
return streamParameters;
},
readXRef: function(startXRef) {
readXRef: function readXref(startXRef) {
var stream = this.stream;
stream.pos = startXRef;
var parser = new Parser(new Lexer(stream), true);
@ -2709,6 +2736,7 @@ var XRef = (function() {
return this.readXRefStream(obj);
}
error("Invalid XRef");
return null;
},
getEntry: function(i) {
var e = this.entries[i];
@ -2752,7 +2780,11 @@ var XRef = (function() {
}
error("bad XRef entry");
}
e = parser.getObj();
if (this.encrypt) {
e = parser.getObj(this.encrypt.createCipherTransform(num, gen));
} else {
e = parser.getObj();
}
// Don't cache streams since they are mutable.
if (!IsStream(e))
this.cache[num] = e;
@ -3374,7 +3406,7 @@ var CanvasGraphics = (function() {
if (!fd)
// XXX deprecated "special treatment" for standard
// fonts? What do we need to do here?
return;
return null;
var descriptor = xref.fetch(fd);
var fontName = descriptor.get("FontName");
@ -3386,16 +3418,9 @@ var CanvasGraphics = (function() {
error("FontFile not found for font: " + fontName);
fontFile = xref.fetchIfRef(fontFile);
// Fonts with an embedded cmap but without any assignment in
// it are not yet supported, so ask the fonts loader to ignore
// them to not pay a stupid one sec latence.
var ignoreFont = false;
var encodingMap = {};
var charset = [];
if (fontDict.has("Encoding")) {
ignoreFont = false;
var encoding = xref.fetchIfRef(fontDict.get("Encoding"));
if (IsDict(encoding)) {
// Build a map between codes and glyphs
@ -3418,9 +3443,8 @@ var CanvasGraphics = (function() {
error("Unknown font encoding");
var index = 0;
for (var j = 0; j < encoding.length; j++) {
for (var j = 0; j < encoding.length; j++)
encodingMap[index++] = GlyphsUnicode[encoding[j]];
}
var firstChar = xref.fetchIfRef(fontDict.get("FirstChar"));
var widths = xref.fetchIfRef(fontDict.get("Widths"));
@ -3444,13 +3468,7 @@ var CanvasGraphics = (function() {
var tokens = [];
var token = "";
var length = cmapObj.length;
if (cmapObj instanceof FlateStream) {
cmapObj.readBlock();
length = cmapObj.bufferLength;
}
var cmap = cmapObj.getBytes(length);
var cmap = cmapObj.getBytes(cmapObj.length);
for (var i =0; i < cmap.length; i++) {
var byte = cmap[i];
if (byte == 0x20 || byte == 0x0A || byte == 0x3C || byte == 0x3E) {
@ -3460,7 +3478,6 @@ var CanvasGraphics = (function() {
break;
case "beginbfrange":
ignoreFont = false;
case "begincodespacerange":
token = "";
tokens = [];
@ -3507,16 +3524,19 @@ var CanvasGraphics = (function() {
}
var subType = fontDict.get("Subtype");
var bbox = descriptor.get("FontBBox");
assertWellFormed(IsName(subType) && IsArray(bbox),
"invalid font Subtype or FontBBox");
assertWellFormed(IsName(subType), "invalid font Subtype");
var properties = {
type: subType.name,
encoding: encodingMap,
charset: charset,
bbox: bbox,
ignore: ignoreFont
bbox: descriptor.get("FontBBox"),
ascent: descriptor.get("Ascent"),
descent: descriptor.get("Descent"),
xHeight: descriptor.get("XHeight"),
capHeight: descriptor.get("CapHeight"),
flags: descriptor.get("Flags"),
italicAngle: descriptor.get("ItalicAngle")
};
return {
@ -4027,7 +4047,7 @@ var CanvasGraphics = (function() {
this.restore();
TODO("Inverse pattern is painted");
var pattern = this.ctx.createPattern(tmpCanvas, "repeat");
pattern = this.ctx.createPattern(tmpCanvas, "repeat");
this.ctx.fillStyle = pattern;
},
setStrokeGray: function(gray) {