Merge pull request #27 from notmasteryet/objstm

Ability to fetch ObjStm objects; multi-item page content
This commit is contained in:
andreasgal 2011-06-19 22:14:44 -07:00
commit b1cd32fc9c

80
pdf.js
View File

@ -308,7 +308,7 @@ var FlateStream = (function() {
getByte: function() { getByte: function() {
var bufferLength = this.bufferLength; var bufferLength = this.bufferLength;
var pos = this.pos; var pos = this.pos;
if (bufferLength == pos) { if (bufferLength <= pos) {
if (this.eof) if (this.eof)
return; return;
this.readBlock(); this.readBlock();
@ -333,7 +333,7 @@ var FlateStream = (function() {
lookChar: function() { lookChar: function() {
var bufferLength = this.bufferLength; var bufferLength = this.bufferLength;
var pos = this.pos; var pos = this.pos;
if (bufferLength == pos) { if (bufferLength <= pos) {
if (this.eof) if (this.eof)
return; return;
this.readBlock(); this.readBlock();
@ -599,7 +599,7 @@ var PredictorStream = (function() {
var DecryptStream = (function() { var DecryptStream = (function() {
function constructor(str, fileKey, encAlgorithm, keyLength) { function constructor(str, fileKey, encAlgorithm, keyLength) {
// TODO TODO("decrypt stream is not implemented");
} }
constructor.prototype = Stream.prototype; constructor.prototype = Stream.prototype;
@ -1475,11 +1475,12 @@ var XRef = (function() {
e = this.getEntry(num); e = this.getEntry(num);
var gen = ref.gen; var gen = ref.gen;
var stream, parser;
if (e.uncompressed) { if (e.uncompressed) {
if (e.gen != gen) if (e.gen != gen)
throw("inconsistent generation in XRef"); throw("inconsistent generation in XRef");
var stream = this.stream.makeSubStream(e.offset); stream = this.stream.makeSubStream(e.offset);
var parser = new Parser(new Lexer(stream), true, this); parser = new Parser(new Lexer(stream), true, this);
var obj1 = parser.getObj(); var obj1 = parser.getObj();
var obj2 = parser.getObj(); var obj2 = parser.getObj();
var obj3 = parser.getObj(); var obj3 = parser.getObj();
@ -1503,7 +1504,39 @@ var XRef = (function() {
this.cache[num] = e; this.cache[num] = e;
return e; return e;
} }
error("compressed entry"); // compressed entry
stream = this.fetch({num:e.offset, gen:0});
if (!IsStream(stream))
error("bad ObjStm stream");
var first = stream.parameters.get("First");
var n = stream.parameters.get("N");
if (!IsInt(first) || !IsInt(n)) {
error("invalid first and n parameters for ObjStm stream");
}
parser = new Parser(new Lexer(stream), false);
var i, entries = [], nums = [];
// read the object numbers to populate cache
for (i = 0; i < n; ++i) {
var num = parser.getObj();
if (!IsInt(num)) {
error("invalid object number in the ObjStm stream");
}
nums.push(num);
var offset = parser.getObj();
if (!IsInt(offset)) {
error("invalid object offset in the ObjStm stream");
}
}
// read stream objects for cache
for (i = 0; i < n; ++i) {
entries.push(parser.getObj());
this.cache[nums[i]] = entries[i];
}
e = entries[e.gen];
if (!e) {
error("bad XRef entry for compressed object");
}
return e;
}, },
getCatalogObj: function() { getCatalogObj: function() {
return this.fetch(this.root); return this.fetch(this.root);
@ -1534,20 +1567,39 @@ var Page = (function() {
: null)); : null));
}, },
compile: function(gfx, fonts) { compile: function(gfx, fonts) {
if (!this.code) { if (this.code) {
var xref = this.xref; // content was compiled
var content = xref.fetchIfRef(this.content); return;
var resources = xref.fetchIfRef(this.resources);
this.code = gfx.compile(content, xref, resources, fonts);
} }
var xref = this.xref;
var content;
var resources = xref.fetchIfRef(this.resources);
if (!IsArray(this.content)) {
// content is not an array, shortcut
content = xref.fetchIfRef(this.content);
this.code = gfx.compile(content, xref, resources, fonts);
return;
}
// the content is an array, compiling all items
var i, n = this.content.length, compiledItems = [];
for (i = 0; i < n; ++i) {
content = xref.fetchIfRef(this.content[i]);
compiledItems.push(gfx.compile(content, xref, resources, fonts));
}
// creating the function that executes all compiled items
this.code = function(gfx) {
var i, n = compiledItems.length;
for (i = 0; i < n; ++i) {
compiledItems[i](gfx);
}
};
}, },
display: function(gfx) { display: function(gfx) {
assert(this.code instanceof Function, "page content must be compiled first");
var xref = this.xref; var xref = this.xref;
var content = xref.fetchIfRef(this.content);
var resources = xref.fetchIfRef(this.resources); var resources = xref.fetchIfRef(this.resources);
var mediaBox = xref.fetchIfRef(this.mediaBox); var mediaBox = xref.fetchIfRef(this.mediaBox);
assertWellFormed(IsStream(content) && IsDict(resources), assertWellFormed(IsDict(resources), "invalid page resources");
"invalid page content or resources");
gfx.beginDrawing({ x: mediaBox[0], y: mediaBox[1], gfx.beginDrawing({ x: mediaBox[0], y: mediaBox[1],
width: mediaBox[2] - mediaBox[0], width: mediaBox[2] - mediaBox[0],
height: mediaBox[3] - mediaBox[1] }); height: mediaBox[3] - mediaBox[1] });