compile PDF command streams into JS code

This commit is contained in:
Andreas Gal 2011-06-14 18:31:14 -07:00
parent bf2c525788
commit b9771416ba

136
pdf.js
View File

@ -1395,8 +1395,7 @@ var Page = (function() {
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] });
gfx.interpret(new Parser(new Lexer(contents), false), gfx.execute(contents, xref, resources);
xref, resources);
gfx.endDrawing(); gfx.endDrawing();
} }
}; };
@ -1605,65 +1604,65 @@ var CanvasGraphics = (function() {
this.xobjs = null; this.xobjs = null;
this.map = { this.map = {
// Graphics state // Graphics state
w: this.setLineWidth, w: "setLineWidth",
J: this.setLineCap, J: "setLineCap",
j: this.setLineJoin, j: "setLineJoin",
d: this.setDash, d: "setDash",
ri: this.setRenderingIntent, ri: "setRenderingIntent",
i: this.setFlatness, i: "setFlatness",
gs: this.setGState, gs: "setGState",
q: this.save, q: "save",
Q: this.restore, Q: "restore",
cm: this.transform, cm: "transform",
// Path // Path
m: this.moveTo, m: "moveTo",
l: this.lineTo, l: "lineTo",
c: this.curveTo, c: "curveTo",
h: this.closePath, h: "closePath",
re: this.rectangle, re: "rectangle",
S: this.stroke, S: "stroke",
f: this.fill, f: "fill",
"f*": this.eoFill, "f*": "eoFill",
B: this.fillStroke, B: "fillStroke",
b: this.closeFillStroke, b: "closeFillStroke",
n: this.endPath, n: "endPath",
// Clipping // Clipping
W: this.clip, W: "clip",
"W*": this.eoClip, "W*": "eoClip",
// Text // Text
BT: this.beginText, BT: "beginText",
ET: this.endText, ET: "endText",
TL: this.setLeading, TL: "setLeading",
Tf: this.setFont, Tf: "setFont",
Td: this.moveText, Td: "moveText",
Tm: this.setTextMatrix, Tm: "setTextMatrix",
"T*": this.nextLine, "T*": "nextLine",
Tj: this.showText, Tj: "showText",
TJ: this.showSpacedText, TJ: "showSpacedText",
// Type3 fonts // Type3 fonts
// Color // Color
CS: this.setStrokeColorSpace, CS: "setStrokeColorSpace",
cs: this.setFillColorSpace, cs: "setFillColorSpace",
SC: this.setStrokeColor, SC: "setStrokeColor",
SCN: this.setStrokeColorN, SCN: "setStrokeColorN",
sc: this.setFillColor, sc: "setFillColor",
scn: this.setFillColorN, scn: "setFillColorN",
G: this.setStrokeGray, G: "setStrokeGray",
g: this.setFillGray, g: "setFillGray",
RG: this.setStrokeRGBColor, RG: "setStrokeRGBColor",
rg: this.setFillRGBColor, rg: "setFillRGBColor",
// Shading // Shading
sh: this.shadingFill, sh: "shadingFill",
// Images // Images
// XObjects // XObjects
Do: this.paintXObject, Do: "paintXObject",
// Marked content // Marked content
// Compatibility // Compatibility
@ -1683,13 +1682,38 @@ var CanvasGraphics = (function() {
this.ctx.translate(0, -mediaBox.height); this.ctx.translate(0, -mediaBox.height);
}, },
interpret: function(parser, xref, resources) { execute: function(stream, xref, resources) {
if (!stream.execute)
this.compile(stream, xref, resources);
var savedXref = this.xref, savedRes = this.res, savedXobjs = this.xobjs; var savedXref = this.xref, savedRes = this.res, savedXobjs = this.xobjs;
this.xref = xref; this.xref = xref;
this.res = resources || new Dict(); this.res = resources || new Dict();
this.xobjs = this.res.get("XObject") || new Dict(); this.xobjs = this.res.get("XObject") || new Dict();
this.xobjs = this.xref.fetchIfRef(this.xobjs); this.xobjs = this.xref.fetchIfRef(this.xobjs);
stream.execute(this, stream.objpool);
this.xobjs = savedXobjs;
this.res = savedRes;
this.xref = savedXref;
},
compile: function(stream, xref, resources) {
var parser = new Parser(new Lexer(stream), false);
var objpool = [];
function emitArg(arg) {
if (typeof arg == "object" || typeof arg == "string") {
var index = objpool.length;
objpool[index] = arg;
return "objpool[" + index + "]";
}
return arg;
}
var src = "{\n";
var args = []; var args = [];
var map = this.map; var map = this.map;
var obj; var obj;
@ -1699,7 +1723,12 @@ var CanvasGraphics = (function() {
var fn = map[cmd]; var fn = map[cmd];
assertWellFormed(fn, "Unknown command '" + cmd + "'"); assertWellFormed(fn, "Unknown command '" + cmd + "'");
// TODO figure out how to type-check vararg functions // TODO figure out how to type-check vararg functions
fn.apply(this, args);
src += "gfx.";
src += fn;
src += "(";
src += args.map(emitArg).join(",");
src += ");\n";
args.length = 0; args.length = 0;
} else { } else {
@ -1708,9 +1737,10 @@ var CanvasGraphics = (function() {
} }
} }
this.xobjs = savedXobjs; src += "}";
this.res = savedRes;
this.xref = savedXref; stream.execute = new Function("gfx", "objpool", src);
stream.objpool = objpool;
}, },
endDrawing: function() { endDrawing: function() {
@ -2026,9 +2056,7 @@ var CanvasGraphics = (function() {
this.clip(); this.clip();
this.endPath(); this.endPath();
} }
this.execute(form, this.xref, form.dict.get("Resources"));
this.interpret(new Parser(new Lexer(form), false),
this.xref, form.dict.get("Resources"));
this.restore(); this.restore();
}, },