From 68f1ca51ce9ec8fbbf8989637bb45317af408e37 Mon Sep 17 00:00:00 2001
From: Chris Jones <jones.chris.g@gmail.com>
Date: Thu, 5 May 2011 22:20:07 -0500
Subject: [PATCH 1/3] Basic transforms of PDF page/text space to canvas space

---
 pdf.js    | 26 +++++++++++++++++++++++++-
 test.html |  4 +---
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/pdf.js b/pdf.js
index 73f6b4b34..a38d9e866 100644
--- a/pdf.js
+++ b/pdf.js
@@ -761,6 +761,8 @@ var Interpreter = (function() {
             return this.interpretHelper(new Parser(new Lexer(obj), true));
         },
         interpretHelper: function(parser) {
+            this.gfx.beginDrawing();
+
             var args = [ ];
             var obj;
             while (!((obj = parser.getObj()).isEOF())) {
@@ -781,6 +783,8 @@ var Interpreter = (function() {
                     args.push(obj);
                 }
             }
+
+            this.gfx.endDrawing();
         },
         typeCheck: function(params, args) {
             if (params.length != args.length)
@@ -806,6 +810,11 @@ var EchoGraphics = (function() {
     }
 
     constructor.prototype = {
+        beginDrawing: function () {
+        },
+        endDrawing: function () {
+        },
+
         // Graphics state
         setLineWidth: function(width) {
             this.printdentln(width +" w");
@@ -934,13 +943,22 @@ var CanvasExtraState = (function() {
 })();
 
 var CanvasGraphics = (function() {
-    function constructor(canvasCtx, hdpi, vdpi, pageBox) {
+    function constructor(canvasCtx) {
         this.ctx = canvasCtx;
         this.current = new CanvasExtraState();
         this.stateStack = [ ];
     }
 
     constructor.prototype = {
+        beginDrawing: function () {
+            this.ctx.save();
+            this.ctx.scale(1, -1);
+            this.ctx.translate(0, -this.ctx.canvas.height);
+        },
+        endDrawing: function () {
+            this.ctx.restore();
+        },
+
         // Graphics state
         setLineWidth: function(width) {
             this.ctx.lineWidth = width;
@@ -1011,7 +1029,13 @@ var CanvasGraphics = (function() {
             this.current.lineY = y;
         },
         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.restore();
         },
 
         // Type3 fonts
diff --git a/test.html b/test.html
index 5d446c8f5..a0d293225 100644
--- a/test.html
+++ b/test.html
@@ -26,12 +26,10 @@ function displayPage(number) {
     pageDisplay.value = number;
 
     var ctx = canvas.getContext("2d");
-    ctx.save();
     ctx.clearRect(0, 0, canvas.width, canvas.height);
-    var gfx = new CanvasGraphics(ctx, 96.0, 96.0, null);
+    var gfx = new CanvasGraphics(ctx);
     var interp = new Interpreter(null, page.res, null, gfx);
     interp.interpretHelper(new MockParser(page.objs));
-    ctx.restore();
 }
 
 function nextPage() {

From 7827e91566a47993cd104c457951b062a8038f8f Mon Sep 17 00:00:00 2001
From: Chris Jones <jones.chris.g@gmail.com>
Date: Thu, 5 May 2011 23:46:54 -0500
Subject: [PATCH 2/3] Respect media box

---
 pdf.js    | 32 +++++++++++++++++++++-----------
 test.html | 22 +++++++++++++++++-----
 2 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/pdf.js b/pdf.js
index a38d9e866..98b097744 100644
--- a/pdf.js
+++ b/pdf.js
@@ -760,8 +760,10 @@ var Interpreter = (function() {
         interpret: function(obj) {
             return this.interpretHelper(new Parser(new Lexer(obj), true));
         },
-        interpretHelper: function(parser) {
-            this.gfx.beginDrawing();
+        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 obj;
@@ -810,9 +812,12 @@ var EchoGraphics = (function() {
     }
 
     constructor.prototype = {
-        beginDrawing: function () {
+        beginDrawing: function(mediaBox) {
+            this.printdentln("/MediaBox ["+
+                             mediaBox.x +" "+ mediaBox.y +" "+
+                             mediaBox.width +" "+ mediaBox.height +" ]");
         },
-        endDrawing: function () {
+        endDrawing: function() {
         },
 
         // Graphics state
@@ -950,10 +955,11 @@ var CanvasGraphics = (function() {
     }
 
     constructor.prototype = {
-        beginDrawing: function () {
+        beginDrawing: function(mediaBox) {
+            var cw = this.ctx.canvas.width, ch = this.ctx.canvas.height;
             this.ctx.save();
-            this.ctx.scale(1, -1);
-            this.ctx.translate(0, -this.ctx.canvas.height);
+            this.ctx.scale(cw / mediaBox.width, -ch / mediaBox.height);
+            this.ctx.translate(0, -mediaBox.height);
         },
         endDrawing: function () {
             this.ctx.restore();
@@ -1103,11 +1109,12 @@ var tests = [
               F1: { Type: "Font",
                     Subtype: "Type1",
                     Name: "F1",
-                    BaseFont: "Georgia",
+                    BaseFont: "Helvetica",
                     Encoding: "MacRomanEncoding"
               },
           }
       },
+      mediaBox: [ 0, 0, 612, 792 ],
       objs: [
           cmd("BT"),
           name("F1"), int(24), cmd("Tf"),
@@ -1115,10 +1122,11 @@ var tests = [
           string("Hello World"), cmd("Tj"),
           cmd("ET"),
           eof()
-          ]
+      ]
     },
     { name: "Simple graphics",
       res: { },
+      mediaBox: [ 0, 0, 612, 792 ],
       objs: [
           int(150), int(250), cmd("m"),
           int(150), int(350), cmd("l"),
@@ -1147,6 +1155,7 @@ var tests = [
     },
     { name: "Heart",
       res: { },
+      mediaBox: [ 0, 0, 612, 792 ],
       objs: [
           cmd("q"),
           real(0.9), real(0.0), real(0.0), cmd("rg"),
@@ -1164,6 +1173,7 @@ var tests = [
     },
     { name: "Rectangle",
       res: { },
+      mediaBox: [ 0, 0, 612, 792 ],
       objs: [
           int(1), int(0), int(0), int(1), int(80), int(80), cmd("cm"),
           int(0), int(72), cmd("m"),
@@ -1173,7 +1183,7 @@ var tests = [
           int(4), cmd("w"),
           cmd("h"), cmd("S"),
           eof()
-     ]
+      ]
     },
 ];
 
@@ -1185,7 +1195,7 @@ function runEchoTests() {
         var output = "";
         var gfx = new EchoGraphics(output);
         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(gfx.out);
diff --git a/test.html b/test.html
index a0d293225..95a41c223 100644
--- a/test.html
+++ b/test.html
@@ -4,11 +4,19 @@
   <script type="application/javascript;version=1.8"
           src="pdf.js"></script>
   <style type"text/css">
+body {
+  margin: 6px;
+  padding: 0px;
+  background-color: #c0bdb7;
+}
 #viewer {
-  padding: 5px;
-  border: 5px solid black;
+  margin: auto;
+  border: 1px solid black;
   width: 8.5in;
   height: 11in;
+}
+#pageNumber {
+  text-align: right;
 }
   </style>
 
@@ -26,10 +34,14 @@ function displayPage(number) {
     pageDisplay.value = number;
 
     var ctx = canvas.getContext("2d");
-    ctx.clearRect(0, 0, canvas.width, canvas.height);
+    ctx.save();
+    ctx.fillStyle = "rgb(255, 255, 255)";
+    ctx.fillRect(0, 0, canvas.width, canvas.height);
+    ctx.restore();
+
     var gfx = new CanvasGraphics(ctx);
     var interp = new Interpreter(null, page.res, null, gfx);
-    interp.interpretHelper(new MockParser(page.objs));
+    interp.interpretHelper(page.mediaBox, new MockParser(page.objs));
 }
 
 function nextPage() {
@@ -60,8 +72,8 @@ function profile() {
 <body onload="load();">
   <div>
     <button onclick="prevPage();">Previous</button>
-    <input type="text" id="pageNumber" value="0"></input>
     <button onclick="nextPage();">Next</button>
+    <input type="text" id="pageNumber" value="0" size="5"></input>
     <button onclick="profile();">Profile</button>
   <div id="viewer">
     <!-- Canvas dimensions must be specified in CSS pixels.  CSS pixels

From e655fd0adb8e397512eae488e1aba185befbe259 Mon Sep 17 00:00:00 2001
From: Chris Jones <jones.chris.g@gmail.com>
Date: Fri, 6 May 2011 00:42:43 -0500
Subject: [PATCH 3/3] Lower the common denominator

---
 pdf.js    | 15 ++++++++-------
 test.html |  4 ++--
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/pdf.js b/pdf.js
index 98b097744..a97856de7 100644
--- a/pdf.js
+++ b/pdf.js
@@ -72,14 +72,14 @@ var Obj = (function() {
                 ];
 
     for (var i = 0; i < types.length; ++i) {
-        let type = i;
-        var typeName = types[type];
-        constructor[typeName] = type;
+        var typeName = types[i];
+        constructor[typeName] = i;
         constructor.prototype["is" + typeName] =
-            (function (value) {
-                return this.type == type &&
+            (function is(value) {
+                return this.type == is.type &&
                        (typeof value == "undefined" || value == this.value);
             });
+        constructor.prototype["is" + typeName].type = i;
     }
 
     constructor.prototype.isNum = function(value) {
@@ -99,7 +99,7 @@ var Obj = (function() {
         } else if (this.isNull()) {
             return null;
         } else if (this.isArray()) {
-            return this.value.map(function (e) e.lowerToJS());
+            return this.value.map(function (e) { return e.lowerToJS(); });
         } else {
             return undefined;
         }
@@ -777,7 +777,8 @@ var Interpreter = (function() {
                     if (!this.typeCheck(op.params, args))
                         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;
                 } else if (MAX_ARGS == args.length) {
                     this.error("Too many arguments");
diff --git a/test.html b/test.html
index 95a41c223..1710ab6bf 100644
--- a/test.html
+++ b/test.html
@@ -1,7 +1,7 @@
 <html>
 <head>
   <title>Simple pdf.js page viewer</title>
-  <script type="application/javascript;version=1.8"
+  <script type="text/javascript"
           src="pdf.js"></script>
   <style type"text/css">
 body {
@@ -20,7 +20,7 @@ body {
 }
   </style>
 
-  <script type="application/javascript;version=1.8">
+  <script type="text/javascript">
 var canvas, numPages, pageDisplay, pageNum;
 function load() {
     canvas = document.getElementById("canvas");