Merge branch 'master' of github.com:andreasgal/pdf.js

This commit is contained in:
Andreas Gal 2011-05-06 01:16:20 -07:00
commit 455c646206
2 changed files with 67 additions and 22 deletions

61
pdf.js
View File

@ -92,14 +92,14 @@ var Obj = (function() {
]; ];
for (var i = 0; i < types.length; ++i) { for (var i = 0; i < types.length; ++i) {
let type = i; var typeName = types[i];
var typeName = types[type]; constructor[typeName] = i;
constructor[typeName] = type;
constructor.prototype["is" + typeName] = constructor.prototype["is" + typeName] =
(function (value) { (function is(value) {
return this.type == type && return this.type == is.type &&
(typeof value == "undefined" || value == this.value); (typeof value == "undefined" || value == this.value);
}); });
constructor.prototype["is" + typeName].type = i;
} }
constructor.prototype.isNum = function(value) { constructor.prototype.isNum = function(value) {
@ -119,7 +119,7 @@ var Obj = (function() {
} else if (this.isNull()) { } else if (this.isNull()) {
return null; return null;
} else if (this.isArray()) { } else if (this.isArray()) {
return this.value.map(function (e) e.lowerToJS()); return this.value.map(function (e) { return e.lowerToJS(); });
} else { } else {
return undefined; return undefined;
} }
@ -788,7 +788,11 @@ var Interpreter = (function() {
interpret: function(obj) { interpret: function(obj) {
return this.interpretHelper(new Parser(new Lexer(obj), true)); return this.interpretHelper(new Parser(new Lexer(obj), true));
}, },
interpretHelper: function(parser) { interpretHelper: function(mediaBox, parser) {
this.gfx.beginDrawing({ x: mediaBox[0], y: mediaBox[1],
width: mediaBox[2] - mediaBox[0],
height: mediaBox[3] - mediaBox[1] });
var args = [ ]; var args = [ ];
var obj; var obj;
while (!((obj = parser.getObj()).isEOF())) { while (!((obj = parser.getObj()).isEOF())) {
@ -801,7 +805,8 @@ var Interpreter = (function() {
if (!this.typeCheck(op.params, args)) if (!this.typeCheck(op.params, args))
this.error("Wrong arguments for command '"+ cmd +"'"); this.error("Wrong arguments for command '"+ cmd +"'");
op.op.call(this, args.map(function (a) a.lowerToJS())); op.op.call(this,
args.map(function (a) { return a.lowerToJS() }));
args.length = 0; args.length = 0;
} else if (MAX_ARGS == args.length) { } else if (MAX_ARGS == args.length) {
this.error("Too many arguments"); this.error("Too many arguments");
@ -809,6 +814,8 @@ var Interpreter = (function() {
args.push(obj); args.push(obj);
} }
} }
this.gfx.endDrawing();
}, },
typeCheck: function(params, args) { typeCheck: function(params, args) {
if (params.length != args.length) if (params.length != args.length)
@ -834,6 +841,14 @@ var EchoGraphics = (function() {
} }
constructor.prototype = { constructor.prototype = {
beginDrawing: function(mediaBox) {
this.printdentln("/MediaBox ["+
mediaBox.x +" "+ mediaBox.y +" "+
mediaBox.width +" "+ mediaBox.height +" ]");
},
endDrawing: function() {
},
// Graphics state // Graphics state
setLineWidth: function(width) { setLineWidth: function(width) {
this.printdentln(width +" w"); this.printdentln(width +" w");
@ -962,13 +977,23 @@ var CanvasExtraState = (function() {
})(); })();
var CanvasGraphics = (function() { var CanvasGraphics = (function() {
function constructor(canvasCtx, hdpi, vdpi, pageBox) { function constructor(canvasCtx) {
this.ctx = canvasCtx; this.ctx = canvasCtx;
this.current = new CanvasExtraState(); this.current = new CanvasExtraState();
this.stateStack = [ ]; this.stateStack = [ ];
} }
constructor.prototype = { constructor.prototype = {
beginDrawing: function(mediaBox) {
var cw = this.ctx.canvas.width, ch = this.ctx.canvas.height;
this.ctx.save();
this.ctx.scale(cw / mediaBox.width, -ch / mediaBox.height);
this.ctx.translate(0, -mediaBox.height);
},
endDrawing: function () {
this.ctx.restore();
},
// Graphics state // Graphics state
setLineWidth: function(width) { setLineWidth: function(width) {
this.ctx.lineWidth = width; this.ctx.lineWidth = width;
@ -1039,7 +1064,13 @@ var CanvasGraphics = (function() {
this.current.lineY = y; this.current.lineY = y;
}, },
showText: function(text) { showText: function(text) {
this.ctx.save();
this.ctx.translate(0, 2 * this.current.lineY);
this.ctx.scale(1, -1);
this.ctx.fillText(text, this.current.lineX, this.current.lineY); this.ctx.fillText(text, this.current.lineX, this.current.lineY);
this.ctx.restore();
}, },
// Type3 fonts // Type3 fonts
@ -1107,11 +1138,12 @@ var tests = [
F1: { Type: "Font", F1: { Type: "Font",
Subtype: "Type1", Subtype: "Type1",
Name: "F1", Name: "F1",
BaseFont: "Georgia", BaseFont: "Helvetica",
Encoding: "MacRomanEncoding" Encoding: "MacRomanEncoding"
}, },
} }
}, },
mediaBox: [ 0, 0, 612, 792 ],
objs: [ objs: [
cmd("BT"), cmd("BT"),
name("F1"), int(24), cmd("Tf"), name("F1"), int(24), cmd("Tf"),
@ -1119,10 +1151,11 @@ var tests = [
string("Hello World"), cmd("Tj"), string("Hello World"), cmd("Tj"),
cmd("ET"), cmd("ET"),
eof() eof()
] ]
}, },
{ name: "Simple graphics", { name: "Simple graphics",
res: { }, res: { },
mediaBox: [ 0, 0, 612, 792 ],
objs: [ objs: [
int(150), int(250), cmd("m"), int(150), int(250), cmd("m"),
int(150), int(350), cmd("l"), int(150), int(350), cmd("l"),
@ -1151,6 +1184,7 @@ var tests = [
}, },
{ name: "Heart", { name: "Heart",
res: { }, res: { },
mediaBox: [ 0, 0, 612, 792 ],
objs: [ objs: [
cmd("q"), cmd("q"),
real(0.9), real(0.0), real(0.0), cmd("rg"), real(0.9), real(0.0), real(0.0), cmd("rg"),
@ -1168,6 +1202,7 @@ var tests = [
}, },
{ name: "Rectangle", { name: "Rectangle",
res: { }, res: { },
mediaBox: [ 0, 0, 612, 792 ],
objs: [ objs: [
int(1), int(0), int(0), int(1), int(80), int(80), cmd("cm"), int(1), int(0), int(0), int(1), int(80), int(80), cmd("cm"),
int(0), int(72), cmd("m"), int(0), int(72), cmd("m"),
@ -1177,7 +1212,7 @@ var tests = [
int(4), cmd("w"), int(4), cmd("w"),
cmd("h"), cmd("S"), cmd("h"), cmd("S"),
eof() eof()
] ]
}, },
]; ];
@ -1189,7 +1224,7 @@ function runEchoTests() {
var output = ""; var output = "";
var gfx = new EchoGraphics(output); var gfx = new EchoGraphics(output);
var i = new Interpreter(null, test.res, null, gfx); var i = new Interpreter(null, test.res, null, gfx);
i.interpretHelper(new MockParser(test.objs)); i.interpretHelper(test.mediaBox, new MockParser(test.objs));
print("done. Output:"); print("done. Output:");
print(gfx.out); print(gfx.out);

View File

@ -1,18 +1,26 @@
<html> <html>
<head> <head>
<title>Simple pdf.js page viewer</title> <title>Simple pdf.js page viewer</title>
<script type="application/javascript;version=1.8" <script type="text/javascript"
src="pdf.js"></script> src="pdf.js"></script>
<style type"text/css"> <style type"text/css">
body {
margin: 6px;
padding: 0px;
background-color: #c0bdb7;
}
#viewer { #viewer {
padding: 5px; margin: auto;
border: 5px solid black; border: 1px solid black;
width: 8.5in; width: 8.5in;
height: 11in; height: 11in;
}
#pageNumber {
text-align: right;
} }
</style> </style>
<script type="application/javascript;version=1.8"> <script type="text/javascript">
var canvas, numPages, pageDisplay, pageNum; var canvas, numPages, pageDisplay, pageNum;
function load() { function load() {
canvas = document.getElementById("canvas"); canvas = document.getElementById("canvas");
@ -27,11 +35,13 @@ function displayPage(number) {
var ctx = canvas.getContext("2d"); var ctx = canvas.getContext("2d");
ctx.save(); ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "rgb(255, 255, 255)";
var gfx = new CanvasGraphics(ctx, 96.0, 96.0, null); ctx.fillRect(0, 0, canvas.width, canvas.height);
var interp = new Interpreter(null, page.res, null, gfx);
interp.interpretHelper(new MockParser(page.objs));
ctx.restore(); ctx.restore();
var gfx = new CanvasGraphics(ctx);
var interp = new Interpreter(null, page.res, null, gfx);
interp.interpretHelper(page.mediaBox, new MockParser(page.objs));
} }
function nextPage() { function nextPage() {
@ -62,8 +72,8 @@ function profile() {
<body onload="load();"> <body onload="load();">
<div> <div>
<button onclick="prevPage();">Previous</button> <button onclick="prevPage();">Previous</button>
<input type="text" id="pageNumber" value="0"></input>
<button onclick="nextPage();">Next</button> <button onclick="nextPage();">Next</button>
<input type="text" id="pageNumber" value="0" size="5"></input>
<button onclick="profile();">Profile</button> <button onclick="profile();">Profile</button>
<div id="viewer"> <div id="viewer">
<!-- Canvas dimensions must be specified in CSS pixels. CSS pixels <!-- Canvas dimensions must be specified in CSS pixels. CSS pixels