get: function(key) {
return this.map[key];
},
+ has: function(key) {
+ return key in this.map;
+ },
set: function(key, value) {
this.map[key] = value;
}
return v instanceof Cmd && (!cmd || v.cmd == cmd);
}
-function IsDict(v) {
- return v instanceof Dict;
+function IsDict(v, type) {
+ return v instanceof Dict && (!type || v.get("Type").name == type);
}
function IsArray(v) {
},
makeFilter: function(stream, name, params) {
print(name);
- for (i in params.map)
- print(i + ": " + params.map[i]);
+ if (params)
+ error("filter params not supported yet");
// TODO
return stream;
}
if (e.gen != gen)
throw("inconsistent generation in XRef");
var stream = this.stream.makeSubStream(e.offset);
- var parser = new Parser(new Lexer(stream));
+ var parser = new Parser(new Lexer(stream), true);
var obj1 = parser.getObj();
var obj2 = parser.getObj();
var obj3 = parser.getObj();
return constructor;
})();
+var Page = (function() {
+ function constructor(xref, pageNumber, pageDict) {
+ this.xref = xref;
+ this.pageNumber = pageNumber;
+ this.pageDict = pageDict;
+ }
+
+ constructor.prototype = {
+ get contents() {
+ var obj = this.pageDict.get("Contents");
+ if (IsRef(obj))
+ obj = this.xref.fetch(obj);
+ if (!(IsArray(obj) || IsStream(obj)))
+ error("invalid page contents object");
+ return this.contents = obj;
+ }
+ };
+
+ return constructor;
+})();
+
var Catalog = (function() {
function constructor(xref) {
this.xref = xref;
}
constructor.prototype = {
- get pagesDict() {
+ get toplevelPagesDict() {
var obj = this.catDict.get("Pages");
if (!IsRef(obj))
error("invalid top-level pages reference");
if (!IsDict(obj))
error("invalid top-level pages dictionary");
// shadow the prototype getter
- return this.pagesDict = obj;
+ return this.toplevelPagesDict = obj;
},
get numPages() {
- obj = this.pagesDict.get("Count");
+ obj = this.toplevelPagesDict.get("Count");
if (!IsInt(obj))
error("page count in top level pages object is not an integer");
// shadow the prototype getter
return this.numPages = obj;
+ },
+ traverseKids: function(pagesDict) {
+ var pageCache = this.pageCache;
+ var kids = pagesDict.get("Kids");
+ if (!IsArray(kids))
+ error("page dictionary kids object is not an array");
+ for (var i = 0; i < kids.length; ++i) {
+ var kid = kids[i];
+ if (!IsRef(kid))
+ error("page dictionary kid is not a reference");
+ var obj = this.xref.fetch(kid);
+ if (IsDict(obj, "Page") || (IsDict(obj) && !obj.has("Kids"))) {
+ pageCache.push(new Page(this.xref, pageCache.length, obj));
+ } else if (IsDict(obj)) { // must be a child page dictionary
+ this.traverseKids(obj);
+ } else {
+ error("page dictionary kid reference points to wrong type of object");
+ }
+ }
+ },
+ getPage: function(n) {
+ var pageCache = this.pageCache;
+ if (!pageCache) {
+ pageCache = this.pageCache = [];
+ this.traverseKids(this.toplevelPagesDict);
+ }
+ return this.pageCache[n];
}
};
// overwrite the prototype getter
return this.numPages = num;
},
- getPage: function(page) {
- print(this.numPages);
- // TODO
+ getPage: function(n) {
+ var linearization = this.linearization;
+ if (linearization) {
+ error("linearized page access not implemented");
+ }
+ return this.catalog.getPage(n);
}
};
//var data = snarf("simple_graphics.pdf", "binary");
var data = snarf("/tmp/paper.pdf", "binary");
var pdf = new PDFDoc(new Stream(data));
- pdf.getPage(1);
+ var page = pdf.getPage(1);
+ var contents = page.contents;
}
if ("arguments" in this) {