tighten up the interpreter loop
This commit is contained in:
parent
36f657b4ad
commit
d65ebb7533
254
pdf.js
254
pdf.js
@ -808,111 +808,9 @@ var Interpreter = (function() {
|
|||||||
this.gfx = graphics;
|
this.gfx = graphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_ARGS = 33;
|
|
||||||
const CMD_TABLE = {
|
|
||||||
// Graphics state
|
|
||||||
w : { params: [ "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.setLineWidth(args[0]);
|
|
||||||
} },
|
|
||||||
d : { params: [ "Array", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.setDash(args[0], args[1]);
|
|
||||||
} },
|
|
||||||
q : { params: [ ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.save();
|
|
||||||
} },
|
|
||||||
Q : { params: [ ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.restore();
|
|
||||||
} },
|
|
||||||
cm: { params: [ "Num", "Num", "Num", "Num", "Num", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.transform(args[0], args[1], args[2], args[3], args[4], args[5]);
|
|
||||||
} },
|
|
||||||
// Path
|
|
||||||
m : { params: [ "Num", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.moveTo(args[0], args[1]);
|
|
||||||
} },
|
|
||||||
l : { params: [ "Num", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.lineTo(args[0], args[1]);
|
|
||||||
} },
|
|
||||||
c : { params: [ "Num", "Num", "Num", "Num", "Num", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.curveTo(args[0], args[1], args[2], args[3], args[4], args[5]);
|
|
||||||
} },
|
|
||||||
h : { params: [ ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.closePath();
|
|
||||||
} },
|
|
||||||
re: { params: [ "Num", "Num", "Num", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.rectangle(args[0], args[1], args[2], args[3]);
|
|
||||||
} },
|
|
||||||
S : { params: [ ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.stroke();
|
|
||||||
} },
|
|
||||||
f : { params: [ ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.fill();
|
|
||||||
} },
|
|
||||||
B : { params: [ ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.fillStroke();
|
|
||||||
} },
|
|
||||||
b : { params: [ ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.closeFillStroke();
|
|
||||||
} },
|
|
||||||
// Clipping
|
|
||||||
// Text
|
|
||||||
BT: { params: [ ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.beginText();
|
|
||||||
} },
|
|
||||||
ET: { params: [ ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.endText();
|
|
||||||
} },
|
|
||||||
Tf: { params: [ "Name", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
var font = this.res.Font[args[0]];
|
|
||||||
this.gfx.setFont(font, args[1]);
|
|
||||||
} },
|
|
||||||
Td: { params: [ "Num", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.moveText(args[0], args[1]);
|
|
||||||
} },
|
|
||||||
Tj: { params: [ "String" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.showText(args[0]);
|
|
||||||
} },
|
|
||||||
// Type3 fonts
|
|
||||||
// Color
|
|
||||||
g : { params: [ "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.setFillGray(args[0]);
|
|
||||||
} },
|
|
||||||
RG: { params: [ "Num", "Num", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.setStrokeRGBColor(args[0], args[1], args[2]);
|
|
||||||
} },
|
|
||||||
rg: { params: [ "Num", "Num", "Num" ],
|
|
||||||
op: function(args) {
|
|
||||||
this.gfx.setFillRGBColor(args[0], args[1], args[2]);
|
|
||||||
} },
|
|
||||||
// Shading
|
|
||||||
// Images
|
|
||||||
// XObjects
|
|
||||||
// Marked content
|
|
||||||
// Compatibility
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor.prototype = {
|
constructor.prototype = {
|
||||||
|
compile: function(parser) {
|
||||||
|
},
|
||||||
interpret: function(obj) {
|
interpret: function(obj) {
|
||||||
return this.interpretHelper(new Parser(new Lexer(obj), true));
|
return this.interpretHelper(new Parser(new Lexer(obj), true));
|
||||||
},
|
},
|
||||||
@ -920,38 +818,26 @@ var Interpreter = (function() {
|
|||||||
this.gfx.beginDrawing({ x: mediaBox[0], y: mediaBox[1],
|
this.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] });
|
||||||
|
var args = [];
|
||||||
var args = [ ];
|
var gfx = this.gfx;
|
||||||
var obj;
|
var obj;
|
||||||
while (!IsEOF(obj = parser.getObj())) {
|
while (!IsEOF(obj = parser.getObj())) {
|
||||||
if (IsCmd(obj)) {
|
if (IsCmd(obj)) {
|
||||||
var cmd = obj.cmd;
|
var cmd = obj.cmd;
|
||||||
if (!(cmd in CMD_TABLE))
|
var fn = gfx[cmd];
|
||||||
this.error("Unknown command '"+ cmd +"'");
|
if (fn && cmd[0] != "$") {
|
||||||
|
if (fn.length != args.length)
|
||||||
var op = CMD_TABLE[cmd];
|
this.error("Invalid number of arguments '" + cmd + "'");
|
||||||
//if (!this.typeCheck(op.params, args))
|
fn.apply(gfx, args);
|
||||||
//this.error("Wrong arguments for command '"+ cmd +"'");
|
} else
|
||||||
|
this.error("Unknown command '" + cmd + "'");
|
||||||
op.op.call(this, args);
|
|
||||||
args.length = 0;
|
args.length = 0;
|
||||||
} else if (MAX_ARGS == args.length) {
|
|
||||||
this.error("Too many arguments");
|
|
||||||
} else {
|
} else {
|
||||||
args.push(IsName(obj) ? obj.name : obj);
|
args.push(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.gfx.endDrawing();
|
this.gfx.endDrawing();
|
||||||
},
|
},
|
||||||
typeCheck: function(params, args) {
|
|
||||||
if (params.length != args.length)
|
|
||||||
return false;
|
|
||||||
for (var i = 0; i < params.length; ++i)
|
|
||||||
if (!args[i]["is"+ params[i]]())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
error: function(what) {
|
error: function(what) {
|
||||||
throw new Error(what);
|
throw new Error(what);
|
||||||
},
|
},
|
||||||
@ -977,85 +863,85 @@ var EchoGraphics = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Graphics state
|
// Graphics state
|
||||||
setLineWidth: function(width) {
|
w: function(width) { // setLineWidth
|
||||||
this.printdentln(width +" w");
|
this.printdentln(width +" w");
|
||||||
},
|
},
|
||||||
setDash: function(dashArray, dashPhase) {
|
d: function(dashArray, dashPhase) { // setDash
|
||||||
this.printdentln(""+ dashArray +" "+ dashPhase +" d");
|
this.printdentln(""+ dashArray +" "+ dashPhase +" d");
|
||||||
},
|
},
|
||||||
save: function() {
|
q: function() { // save
|
||||||
this.printdentln("q");
|
this.printdentln("q");
|
||||||
},
|
},
|
||||||
restore: function() {
|
Q: function() { // restore
|
||||||
this.printdentln("Q");
|
this.printdentln("Q");
|
||||||
},
|
},
|
||||||
transform: function(a, b, c, d, e, f) {
|
cm: function(a, b, c, d, e, f) { // transform
|
||||||
this.printdentln(""+ a +" "+ b +" "+ c +
|
this.printdentln(""+ a +" "+ b +" "+ c +
|
||||||
" "+d +" "+ e +" "+ f + " cm");
|
" "+d +" "+ e +" "+ f + " cm");
|
||||||
},
|
},
|
||||||
|
|
||||||
// Path
|
// Path
|
||||||
moveTo: function(x, y) {
|
m: function(x, y) { // moveTo
|
||||||
this.printdentln(""+ x +" "+ y +" m");
|
this.printdentln(""+ x +" "+ y +" m");
|
||||||
},
|
},
|
||||||
lineTo: function(x, y) {
|
l: function(x, y) { // lineTo
|
||||||
this.printdentln(""+ x +" "+ y +" l");
|
this.printdentln(""+ x +" "+ y +" l");
|
||||||
},
|
},
|
||||||
curveTo: function(x1, y1, x2, y2, x3, y3) {
|
c: function(x1, y1, x2, y2, x3, y3) { // curvoTo
|
||||||
this.printdentln(""+ x1 +" "+ y1 +
|
this.printdentln(""+ x1 +" "+ y1 +
|
||||||
" "+ x2 +" "+ y2 +
|
" "+ x2 +" "+ y2 +
|
||||||
" "+ x3 +" "+ y3 + " c");
|
" "+ x3 +" "+ y3 + " c");
|
||||||
},
|
},
|
||||||
closePath: function() {
|
h: function() { // closePath
|
||||||
this.printdentln("h");
|
this.printdentln("h");
|
||||||
},
|
},
|
||||||
rectangle: function(x, y, width, height) {
|
re: function(x, y, width, height) { // rectangle
|
||||||
this.printdentln(""+ x +" "+ y + " "+ width +" "+ height +" re");
|
this.printdentln(""+ x +" "+ y + " "+ width +" "+ height +" re");
|
||||||
},
|
},
|
||||||
stroke: function() {
|
S: function() { // stroke
|
||||||
this.printdentln("S");
|
this.printdentln("S");
|
||||||
},
|
},
|
||||||
fill: function() {
|
f: function() { // fill
|
||||||
this.printdentln("f");
|
this.printdentln("f");
|
||||||
},
|
},
|
||||||
fillStroke: function() {
|
B: function() { // fillStroke
|
||||||
this.printdentln("B");
|
this.printdentln("B");
|
||||||
},
|
},
|
||||||
closeFillStroke: function() {
|
b: function() { // closeFillStroke
|
||||||
this.printdentln("b");
|
this.printdentln("b");
|
||||||
},
|
},
|
||||||
|
|
||||||
// Clipping
|
// Clipping
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
beginText: function() {
|
BT: function() { // beginText
|
||||||
this.printdentln("BT");
|
this.printdentln("BT");
|
||||||
this.indent();
|
this.indent();
|
||||||
},
|
},
|
||||||
endText: function() {
|
ET: function() { // endText
|
||||||
this.dedent();
|
this.dedent();
|
||||||
this.printdentln("ET");
|
this.printdentln("ET");
|
||||||
},
|
},
|
||||||
setFont: function(font, size) {
|
Tf: function(font, size) { // setFont
|
||||||
this.printdentln("/"+ font.Name +" "+ size +" Tf");
|
this.printdentln("/"+ font.name +" "+ size +" Tf");
|
||||||
},
|
},
|
||||||
moveText: function (x, y) {
|
Td: function (x, y) { // moveText
|
||||||
this.printdentln(""+ x +" "+ y +" Td");
|
this.printdentln(""+ x +" "+ y +" Td");
|
||||||
},
|
},
|
||||||
showText: function(text) {
|
Tj: function(text) { // showText
|
||||||
this.printdentln("( "+ text +" ) Tj");
|
this.printdentln("( "+ text +" ) Tj");
|
||||||
},
|
},
|
||||||
|
|
||||||
// Type3 fonts
|
// Type3 fonts
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
setFillGray: function(gray) {
|
g: function(gray) { // setFillGray
|
||||||
this.printdentln(""+ gray +" g");
|
this.printdentln(""+ gray +" g");
|
||||||
},
|
},
|
||||||
setStrokeRGBColor: function(r, g, b) {
|
RG: function(r, g, b) { // setStrokeRGBColor
|
||||||
this.printdentln(""+ r +" "+ g +" "+ b +" RG");
|
this.printdentln(""+ r +" "+ g +" "+ b +" RG");
|
||||||
},
|
},
|
||||||
setFillRGBColor: function(r, g, b) {
|
rg: function(r, g, b) { // setFillRGBColor
|
||||||
this.printdentln(""+ r +" "+ g +" "+ b +" rg");
|
this.printdentln(""+ r +" "+ g +" "+ b +" rg");
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1122,75 +1008,75 @@ var CanvasGraphics = (function() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Graphics state
|
// Graphics state
|
||||||
setLineWidth: function(width) {
|
w: function(width) { // setLineWidth
|
||||||
this.ctx.lineWidth = width;
|
this.ctx.lineWidth = width;
|
||||||
},
|
},
|
||||||
setDash: function(dashArray, dashPhase) {
|
d: function(dashArray, dashPhase) { // setDash
|
||||||
// NYI
|
// TODO
|
||||||
},
|
},
|
||||||
save: function() {
|
q: function() { // save
|
||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
this.stateStack.push(this.current);
|
this.stateStack.push(this.current);
|
||||||
this.current = new CanvasExtraState();
|
this.current = new CanvasExtraState();
|
||||||
},
|
},
|
||||||
restore: function() {
|
Q: function() { // restore
|
||||||
this.current = this.stateStack.pop();
|
this.current = this.stateStack.pop();
|
||||||
this.ctx.restore();
|
this.ctx.restore();
|
||||||
},
|
},
|
||||||
transform: function(a, b, c, d, e, f) {
|
cm: function(a, b, c, d, e, f) { // transform
|
||||||
this.ctx.transform(a, b, c, d, e, f);
|
this.ctx.transform(a, b, c, d, e, f);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Path
|
// Path
|
||||||
moveTo: function(x, y) {
|
m: function(x, y) { // moveTo
|
||||||
this.ctx.moveTo(x, y);
|
this.ctx.moveTo(x, y);
|
||||||
},
|
},
|
||||||
lineTo: function(x, y) {
|
l: function(x, y) { // lineTo
|
||||||
this.ctx.lineTo(x, y);
|
this.ctx.lineTo(x, y);
|
||||||
},
|
},
|
||||||
curveTo: function(x1, y1, x2, y2, x3, y3) {
|
c: function(x1, y1, x2, y2, x3, y3) { // curveTo
|
||||||
this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
|
this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
|
||||||
},
|
},
|
||||||
closePath: function() {
|
h: function() { // closePath
|
||||||
this.ctx.closePath();
|
this.ctx.closePath();
|
||||||
},
|
},
|
||||||
rectangle: function(x, y, width, height) {
|
re: function(x, y, width, height) { // rectangle
|
||||||
this.ctx.rect(x, y, width, height);
|
this.ctx.rect(x, y, width, height);
|
||||||
},
|
},
|
||||||
stroke: function() {
|
S: function() { // stroke
|
||||||
this.ctx.stroke();
|
this.ctx.stroke();
|
||||||
this.consumePath();
|
this.$consumePath();
|
||||||
},
|
},
|
||||||
fill: function() {
|
f: function() { // fill
|
||||||
this.ctx.fill();
|
this.ctx.fill();
|
||||||
this.consumePath();
|
this.$consumePath();
|
||||||
},
|
},
|
||||||
fillStroke: function() {
|
B: function() { // fillStroke
|
||||||
this.ctx.fill();
|
this.ctx.fill();
|
||||||
this.ctx.stroke();
|
this.ctx.stroke();
|
||||||
this.consumePath();
|
this.$consumePath();
|
||||||
},
|
},
|
||||||
closeFillStroke: function() {
|
b: function() { // closeFillStroke
|
||||||
return this.fillStroke();
|
return this.B(); // fillStroke
|
||||||
},
|
},
|
||||||
|
|
||||||
// Clipping
|
// Clipping
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
beginText: function() {
|
BT: function() { // beginText
|
||||||
|
// TODO
|
||||||
},
|
},
|
||||||
endText: function() {
|
ET: function() { // endText
|
||||||
|
// TODO
|
||||||
},
|
},
|
||||||
setFont: function(font, size) {
|
Tf: function(font, size) { // setFont
|
||||||
this.ctx.font = size +'px '+ font.BaseFont;
|
this.ctx.font = size +'px '+ font.BaseFont;
|
||||||
},
|
},
|
||||||
moveText: function (x, y) {
|
Td: function (x, y) { // moveText
|
||||||
this.current.lineX = x;
|
this.current.lineX = x;
|
||||||
this.current.lineY = y;
|
this.current.lineY = y;
|
||||||
},
|
},
|
||||||
showText: function(text) {
|
Tj: function(text) { // showText
|
||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
this.ctx.translate(0, 2 * this.current.lineY);
|
this.ctx.translate(0, 2 * this.current.lineY);
|
||||||
this.ctx.scale(1, -1);
|
this.ctx.scale(1, -1);
|
||||||
@ -1203,20 +1089,22 @@ var CanvasGraphics = (function() {
|
|||||||
// Type3 fonts
|
// Type3 fonts
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
setFillGray: function(gray) {
|
g: function(gray) { // setFillGray
|
||||||
this.setFillRGBColor(gray, gray, gray);
|
this.rg(gray, gray, gray); // setFillRGBColor
|
||||||
},
|
},
|
||||||
setStrokeRGBColor: function(r, g, b) {
|
RG: function(r, g, b) { // setStrokeRGBColor
|
||||||
this.ctx.strokeStyle = this.makeCssRgb(r, g, b);
|
this.ctx.strokeStyle = this.$makeCssRgb(r, g, b);
|
||||||
},
|
},
|
||||||
setFillRGBColor: function(r, g, b) {
|
rg: function(r, g, b) { // setFillRGBColor
|
||||||
this.ctx.fillStyle = this.makeCssRgb(r, g, b);
|
this.ctx.fillStyle = this.$makeCssRgb(r, g, b);
|
||||||
},
|
},
|
||||||
|
|
||||||
consumePath: function() {
|
// Helper functions that are not allowed to be called directly.
|
||||||
|
|
||||||
|
$consumePath: function() {
|
||||||
this.ctx.beginPath();
|
this.ctx.beginPath();
|
||||||
},
|
},
|
||||||
makeCssRgb: function(r, g, b) {
|
$makeCssRgb: function(r, g, b) {
|
||||||
var ri = (255 * r) | 0, gi = (255 * g) | 0, bi = (255 * b) | 0;
|
var ri = (255 * r) | 0, gi = (255 * g) | 0, bi = (255 * b) | 0;
|
||||||
return "rgb("+ ri +","+ gi +","+ bi +")";
|
return "rgb("+ ri +","+ gi +","+ bi +")";
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user