From a600a3d2ced53005c1f1e358fdcabdfd5766a959 Mon Sep 17 00:00:00 2001
From: Vivien Nicolas <21@vingtetun.org>
Date: Sat, 2 Jul 2011 06:01:43 +0200
Subject: [PATCH 1/9] Fix bustage while merging

---
 fonts.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fonts.js b/fonts.js
index d8b36ecdb..31a5e1fac 100644
--- a/fonts.js
+++ b/fonts.js
@@ -1117,6 +1117,8 @@ var Font = (function () {
       var rule = "@font-face { font-family:'" + fontName + "';src:" + url + "}";
       var styleSheet = document.styleSheets[0];
       styleSheet.insertRule(rule, styleSheet.cssRules.length);
+
+      return rule;
     }
   };
 

From d28c0cb41e777399dd5e833c10f3fd471b10c2e1 Mon Sep 17 00:00:00 2001
From: Vivien Nicolas <21@vingtetun.org>
Date: Sat, 2 Jul 2011 07:54:28 +0200
Subject: [PATCH 2/9] Get rid of FontsUtils

---
 fonts.js | 128 +++++++++++++++++++++----------------------------------
 1 file changed, 49 insertions(+), 79 deletions(-)

diff --git a/fonts.js b/fonts.js
index 31a5e1fac..2cb8260b2 100644
--- a/fonts.js
+++ b/fonts.js
@@ -447,6 +447,29 @@ var Font = (function () {
     return array;
   };
 
+  function int16(bytes) {
+    return (bytes[0] << 8) + (bytes[1] & 0xff);
+  };
+
+  function int32(bytes) {
+    return (bytes[0] << 24) + (bytes[1] << 16) +
+           (bytes[2] << 8) + (bytes[3] & 0xff);
+  };
+
+  function getMaxPower2(number) {
+    var maxPower = 0;
+    var value = number;
+    while (value >= 2) {
+      value /= 2;
+      maxPower++;
+    }
+
+    value = 2;
+    for (var i = 1; i < maxPower; i++)
+      value *= 2;
+    return value;
+  };
+
   function string16(value) {
     return String.fromCharCode((value >> 8) & 0xff) +
            String.fromCharCode(value & 0xff);
@@ -467,7 +490,7 @@ var Font = (function () {
     header += string16(numTables);
 
     // searchRange (2 bytes)
-    var tablesMaxPower2 = FontsUtils.getMaxPower2(numTables);
+    var tablesMaxPower2 = getMaxPower2(numTables);
     var searchRange = tablesMaxPower2 * 16;
     header += string16(searchRange);
 
@@ -488,7 +511,7 @@ var Font = (function () {
 
     // length
     var length = data.length;
-	
+
     // Per spec tables must be 4-bytes align so add padding as needed
     while (data.length & 3)
       data.push(0x00);
@@ -499,7 +522,7 @@ var Font = (function () {
     // checksum
     var checksum = 0;
     for (var i = 0; i < length; i+=4)
-      checksum += FontsUtils.bytesToInteger([data[i], data[i+1], data[i+2], data[i+3]]);
+      checksum += int16([data[i], data[i+1], data[i+2], data[i+3]]);
 
     var tableEntry = tag + string32(checksum) + string32(offset) + string32(length);
     tableEntry = stringToArray(tableEntry);
@@ -546,7 +569,7 @@ var Font = (function () {
     var headerSize = (12 * 2 + (ranges.length * 5 * 2));
     var segCount = ranges.length + 1;
     var segCount2 = segCount * 2;
-    var searchRange = FontsUtils.getMaxPower2(segCount) * 2;
+    var searchRange = getMaxPower2(segCount) * 2;
     var searchEntry = Math.log(segCount) / Math.log(2);
     var rangeShift = 2 * segCount - searchRange;
 
@@ -693,9 +716,9 @@ var Font = (function () {
               String.fromCharCode(tag[2]) +
               String.fromCharCode(tag[3]);
 
-        var checksum = FontsUtils.bytesToInteger(file.getBytes(4));
-        var offset = FontsUtils.bytesToInteger(file.getBytes(4));
-        var length = FontsUtils.bytesToInteger(file.getBytes(4));
+        var checksum = int32(file.getBytes(4));
+        var offset = int32(file.getBytes(4));
+        var length = int32(file.getBytes(4));
 
         // Read the table associated data
         var previousPosition = file.pos;
@@ -716,26 +739,26 @@ var Font = (function () {
       function readOpenTypeHeader(ttf) {
         return {
           version: ttf.getBytes(4),
-          numTables: FontsUtils.bytesToInteger(ttf.getBytes(2)),
-          searchRange: FontsUtils.bytesToInteger(ttf.getBytes(2)),
-          entrySelector: FontsUtils.bytesToInteger(ttf.getBytes(2)),
-          rangeShift: FontsUtils.bytesToInteger(ttf.getBytes(2))
+          numTables: int16(ttf.getBytes(2)),
+          searchRange: int16(ttf.getBytes(2)),
+          entrySelector: int16(ttf.getBytes(2)),
+          rangeShift: int16(ttf.getBytes(2))
         }
       };
 
       function replaceCMapTable(cmap, font, properties) {
         font.pos = (font.start ? font.start : 0) + cmap.length;
 
-        var version = FontsUtils.bytesToInteger(font.getBytes(2));
-        var numTables = FontsUtils.bytesToInteger(font.getBytes(2));
+        var version = int16(font.getBytes(2));
+        var numTables = int16(font.getBytes(2));
 
         for (var i = 0; i < numTables; i++) {
-          var platformID = FontsUtils.bytesToInteger(font.getBytes(2));
-          var encodingID = FontsUtils.bytesToInteger(font.getBytes(2));
-          var offset = FontsUtils.bytesToInteger(font.getBytes(4));
-          var format = FontsUtils.bytesToInteger(font.getBytes(2));
-          var length = FontsUtils.bytesToInteger(font.getBytes(2));
-          var language = FontsUtils.bytesToInteger(font.getBytes(2));
+          var platformID = int16(font.getBytes(2));
+          var encodingID = int16(font.getBytes(2));
+          var offset = int32(font.getBytes(4));
+          var format = int16(font.getBytes(2));
+          var length = int16(font.getBytes(2));
+          var language = int16(font.getBytes(2));
 
           if ((format == 0 && numTables == 1) ||
               (format == 6 && numTables == 1 && !properties.encoding.empty)) {
@@ -757,13 +780,13 @@ var Font = (function () {
             // table. (This looks weird, so I can have missed something), this
             // works on Linux but seems to fails on Mac so let's rewrite the
             // cmap table to a 3-1-4 style
-            var firstCode = FontsUtils.bytesToInteger(font.getBytes(2));
-            var entryCount = FontsUtils.bytesToInteger(font.getBytes(2));
+            var firstCode = int16(font.getBytes(2));
+            var entryCount = int16(font.getBytes(2));
 
             var glyphs = [];
             var min = 0xffff, max = 0;
             for (var j = 0; j < entryCount; j++) {
-              var charcode = FontsUtils.bytesToInteger(font.getBytes(2));
+              var charcode = int16(font.getBytes(2));
               glyphs.push(charcode);
 
               if (charcode < min)
@@ -1125,54 +1148,6 @@ var Font = (function () {
   return constructor;
 })();
 
-
-/**
- * FontsUtils is a static class dedicated to hold codes that are not related
- * to fonts in particular and needs to be share between them.
- */
-var FontsUtils = {
-  _bytesArray: new Uint8Array(4),
-  integerToBytes: function fu_integerToBytes(value, bytesCount) {
-    var bytes = this._bytesArray;
-
-    if (bytesCount == 1) {
-      bytes.set([value]);
-      return bytes[0];
-    } else if (bytesCount == 2) {
-      bytes.set([value >> 8, value & 0xff]);
-      return [bytes[0], bytes[1]];
-    } else if (bytesCount == 4) {
-      bytes.set([value >> 24, value >> 16, value >> 8, value]);
-      return [bytes[0], bytes[1], bytes[2], bytes[3]];
-    }
-
-    error("This number of bytes " + bytesCount + " is not supported");
-    return null;
-  },
-
-  bytesToInteger: function fu_bytesToInteger(bytesArray) {
-    var value = 0;
-    for (var i = 0; i < bytesArray.length; i++)
-      value = (value << 8) + bytesArray[i];
-    return value;
-  },
-
-  getMaxPower2: function fu_getMaxPower2(number) {
-    var maxPower = 0;
-    var value = number;
-    while (value >= 2) {
-      value /= 2;
-      maxPower++;
-    }
-
-    value = 2;
-    for (var i = 1; i < maxPower; i++)
-      value *= 2;
-    return value;
-  }
-};
-
-
 /**
  * Type1Parser encapsulate the needed code for parsing a Type1 font
  * program.
@@ -1619,10 +1594,7 @@ CFF.prototype = {
     if (count == 0)
       return "\x00\x00\x00";
 
-    var data = "";
-    var bytes = FontsUtils.integerToBytes(count, 2);
-    for (var i = 0; i < bytes.length; i++)
-      data += String.fromCharCode(bytes[i]);
+    var data = String.fromCharCode(count >> 8, count & 0xff);
 
     // Next byte contains the offset size use to reference object in the file
     // Actually we're using 0x04 to be sure to be able to store everything
@@ -1632,9 +1604,8 @@ CFF.prototype = {
     // Add another offset after this one because we need a new offset
     var relativeOffset = 1;
     for (var i = 0; i < count + 1; i++) {
-      var bytes = FontsUtils.integerToBytes(relativeOffset, 4);
-      for (var j = 0; j < bytes.length; j++)
-        data += String.fromCharCode(bytes[j]);
+      data += String.fromCharCode(relativeOffset >> 24, relativeOffset >> 16,
+                                  relativeOffset >> 8, relativeOffset & 0xff);
 
       if (objects[i])
         relativeOffset += objects[i].length;
@@ -1829,8 +1800,7 @@ CFF.prototype = {
           if (index == -1)
             index = 0;
 
-          var bytes = FontsUtils.integerToBytes(index, 2);
-          charset += String.fromCharCode(bytes[0]) + String.fromCharCode(bytes[1]);
+          charset += String.fromCharCode(index >> 8, index & 0xff);
         }
         return charset;
       })(this),

From f58983f4e58971600fcb5657dd27ebe700277dc9 Mon Sep 17 00:00:00 2001
From: Vivien Nicolas <21@vingtetun.org>
Date: Sun, 3 Jul 2011 01:17:28 +0200
Subject: [PATCH 3/9] Clean up Fonts.convert()

---
 fonts.js | 144 ++++++++++++++++++++++++-------------------------------
 1 file changed, 63 insertions(+), 81 deletions(-)

diff --git a/fonts.js b/fonts.js
index 8d0ab7516..808553ce9 100644
--- a/fonts.js
+++ b/fonts.js
@@ -944,8 +944,6 @@ var Font = (function () {
     },
 
     convert: function font_convert(fontName, font, properties) {
-      var otf = new Uint8Array(kMaxFontFileSize);
-
       function createNameTable(name) {
   	    // All the strings of the name table should be an odd number of bytes
         if (name.length % 2)
@@ -1008,7 +1006,7 @@ var Font = (function () {
 		    nameTable += strings.join("") + stringsUnicode.join("");
         return nameTable;
       }
-	  
+
 	    function isFixedPitch(glyphs) {
 	      for (var i = 0; i < glyphs.length - 1; i++) {
 		    if (glyphs[i] != glyphs[i+1])
@@ -1017,46 +1015,34 @@ var Font = (function () {
 		    return true;
       };
 
-      // Required Tables
-      var CFF =
-        font.data,   // PostScript Font Program
-        OS2,         // OS/2 and Windows Specific metrics
-        cmap,        // Character to glyphs mapping
-        head,        // Font header
-        hhea,        // Horizontal header
-        hmtx,        // Horizontal metrics
-        maxp,        // Maximum profile
-        name,        // Naming tables
-        post;        // PostScript informations
-      var tables = [CFF, OS2, cmap, head, hhea, hmtx, maxp, name, post];
-
       // The offsets object holds at the same time a representation of where
       // to write the table entry information about a table and another offset
       // representing the offset where to draw the actual data of a particular
       // table
+      var kRequiredTablesCount = 9;
       var offsets = {
         currentOffset: 0,
-        virtualOffset: tables.length * (4 * 4)
+        virtualOffset: 9 * (4 * 4)
       };
 
-      // It there is only one font, offset table is the first bytes of the file
-      createOpenTypeHeader("\x4F\x54\x54\x4F", otf, offsets, tables.length);
+      var otf = new Uint8Array(kMaxFontFileSize);
+      createOpenTypeHeader("\x4F\x54\x54\x4F", otf, offsets, 9);
 
-      /** CFF */
-      createTableEntry(otf, offsets, "CFF ", CFF);
-
-      /** OS/2 */
 	    var charstrings = font.charstrings;
 	    properties.fixedPitch = isFixedPitch(charstrings);
-      OS2 = stringToArray(createOS2Table(properties));
-      createTableEntry(otf, offsets, "OS/2", OS2);
+      var fields = {
+        // PostScript Font Program
+        "CFF ": font.data,
 
-      /** CMAP */
-      cmap = createCMapTable(charstrings.slice());
-      createTableEntry(otf, offsets, "cmap", cmap);
+        // OS/2 and Windows Specific metrics
+        "OS/2": stringToArray(createOS2Table(properties)),
 
-      /** HEAD */
-      head = stringToArray(
+        // Character to glyphs mapping
+        "cmap": createCMapTable(charstrings.slice()),
+
+        // Font header
+        "head": (function() {
+          return stringToArray(
               "\x00\x01\x00\x00" + // Version number
               "\x00\x00\x10\x00" + // fontRevision
               "\x00\x00\x00\x00" + // checksumAdjustement
@@ -1073,63 +1059,59 @@ var Font = (function () {
               "\x00\x11" + // lowestRecPPEM
               "\x00\x00" + // fontDirectionHint
               "\x00\x00" + // indexToLocFormat
-              "\x00\x00"   // glyphDataFormat
-      );
-      createTableEntry(otf, offsets, "head", head);
+              "\x00\x00");  // glyphDataFormat
+        })(),
 
-      /** HHEA */
-      hhea = stringToArray(
-                 "\x00\x01\x00\x00" + // Version number
-                 string16(properties.ascent) + // Typographic Ascent
-                 string16(properties.descent) + // Typographic Descent
-                 "\x00\x00" + // Line Gap
-                 "\xFF\xFF" + // advanceWidthMax
-                 "\x00\x00" + // minLeftSidebearing
-                 "\x00\x00" + // minRightSidebearing
-                 "\x00\x00" + // xMaxExtent
-                 string16(properties.capHeight) + // caretSlopeRise
-                 string16(Math.tan(properties.italicAngle) * properties.xHeight) + // caretSlopeRun
-                 "\x00\x00" + // caretOffset
-                 "\x00\x00" + // -reserved-
-                 "\x00\x00" + // -reserved-
-                 "\x00\x00" + // -reserved-
-                 "\x00\x00" + // -reserved-
-                 "\x00\x00" + // metricDataFormat
-                 string16(charstrings.length + 1) // Number of HMetrics
-      );
-      createTableEntry(otf, offsets, "hhea", hhea);
+        // Horizontal header
+        "hhea": (function() {
+          return stringToArray(
+              "\x00\x01\x00\x00" + // Version number
+              string16(properties.ascent) + // Typographic Ascent
+              string16(properties.descent) + // Typographic Descent
+              "\x00\x00" + // Line Gap
+              "\xFF\xFF" + // advanceWidthMax
+              "\x00\x00" + // minLeftSidebearing
+              "\x00\x00" + // minRightSidebearing
+              "\x00\x00" + // xMaxExtent
+              string16(properties.capHeight) + // caretSlopeRise
+              string16(Math.tan(properties.italicAngle) * properties.xHeight) + // caretSlopeRun
+              "\x00\x00" + // caretOffset
+              "\x00\x00" + // -reserved-
+              "\x00\x00" + // -reserved-
+              "\x00\x00" + // -reserved-
+              "\x00\x00" + // -reserved-
+              "\x00\x00" + // metricDataFormat
+              string16(charstrings.length + 1)); // Number of HMetrics
+        })(),
 
-      /** HMTX */
-      /* For some reasons, probably related to how the backend handle fonts,
-      * Linux seems to ignore this file and prefer the data from the CFF itself
-      * while Windows use this data. So be careful if you hack on Linux and
-      * have to touch the 'hmtx' table
-      */
-      hmtx = "\x00\x00\x00\x00"; // Fake .notdef
-      for (var i = 0; i < charstrings.length; i++) {
-        hmtx += string16(charstrings[i].width) + string16(0);
-      }
-      hmtx = stringToArray(hmtx);
-      createTableEntry(otf, offsets, "hmtx", hmtx);
+        // Horizontal metrics
+        "hmtx": (function() {
+          var hmtx = "\x00\x00\x00\x00"; // Fake .notdef
+          for (var i = 0; i < charstrings.length; i++) {
+            hmtx += string16(charstrings[i].width) + string16(0);
+          }
+          return stringToArray(hmtx);
+        })(),
 
-      /** MAXP */
-      maxp = "\x00\x00\x50\x00" + // Version number
-             string16(charstrings.length + 1); // Num of glyphs
-      maxp = stringToArray(maxp);
-      createTableEntry(otf, offsets, "maxp", maxp);
+        // Maximum profile
+        "maxp": (function() {
+          return stringToArray(
+              "\x00\x00\x50\x00" + // Version number
+             string16(charstrings.length + 1)); // Num of glyphs
+        })(),
 
-      /** NAME */
-      name = stringToArray(createNameTable(fontName));
-      createTableEntry(otf, offsets, "name", name);
+        // Naming tables
+        "name": stringToArray(createNameTable(fontName)),
 
-      /** POST */
-      post = stringToArray(createPostTable(properties));
-      createTableEntry(otf, offsets, "post", post);
+        // PostScript informations
+        "post": stringToArray(createPostTable(properties))
+      };
 
-      // Once all the table entries header are written, dump the data!
-      var tables = [CFF, OS2, cmap, head, hhea, hmtx, maxp, name, post];
-      for (var i = 0; i < tables.length; i++) {
-        var table = tables[i];
+      for (var field in fields)
+        createTableEntry(otf, offsets, field, fields[field]);
+
+      for (var field in fields) {
+        var table = fields[field];
         otf.set(table, offsets.currentOffset);
         offsets.currentOffset += table.length;
       }

From 8d196a96d067d71808d1aed03259cdabdab3fd03 Mon Sep 17 00:00:00 2001
From: sbarman <sbarman@L3CWZ5T.(none)>
Date: Sun, 3 Jul 2011 01:20:30 -0500
Subject: [PATCH 4/9] fix for colorspaces

---
 pdf.js | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/pdf.js b/pdf.js
index 8f869a48a..7e47a3c57 100644
--- a/pdf.js
+++ b/pdf.js
@@ -4380,9 +4380,11 @@ var ColorSpace = (function() {
     constructor.parse = function colorspace_parse(cs, xref, res) {
         if (IsName(cs)) {
             var colorSpaces = res.get("ColorSpace");
-            var refcs = colorSpaces.get(cs.name);
-            if (refcs)
-                cs = refcs;
+            if (colorSpaces) {
+                var refcs = colorSpaces.get(cs.name);
+                if (refcs)
+                    cs = refcs;
+            }
         }
             
         cs = xref.fetchIfRef(cs);

From cdff127eef9d5998f1d1b0df62457570f14fb12d Mon Sep 17 00:00:00 2001
From: Vivien Nicolas <21@vingtetun.org>
Date: Sun, 3 Jul 2011 14:52:00 +0200
Subject: [PATCH 5/9] Let Chrome (and others?) handle Type1 Fonts (TrueType not
 working yet)

---
 fonts.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fonts.js b/fonts.js
index 808553ce9..ebbd0c0b8 100644
--- a/fonts.js
+++ b/fonts.js
@@ -1656,7 +1656,7 @@ CFF.prototype = {
     };
 
     charstrings.sort(function charstrings_sort(a, b) {
-      return a.unicode > b.unicode;
+      return a.unicode - b.unicode;
     });
     return charstrings;
   },

From 597cdb59f9f262f274116b91f6fbacaef224382b Mon Sep 17 00:00:00 2001
From: sbarman <sbarman@L3CWZ5T.(none)>
Date: Sun, 3 Jul 2011 09:23:17 -0500
Subject: [PATCH 6/9] called getStrokeColorSpace instead of getFillColorSapce

---
 pdf.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pdf.js b/pdf.js
index 7e47a3c57..814c99f75 100644
--- a/pdf.js
+++ b/pdf.js
@@ -3946,7 +3946,7 @@ var CanvasGraphics = (function() {
             this.setFillRGBColor.apply(this, color);
         },
         setFillColorN: function(/*...*/) {
-            var cs = this.getStrokeColorSpace();
+            var cs = this.getFillColorSpace();
 
             if (cs.name == "Pattern") {
                 var patternName = arguments[0];

From ac5db21fb1f9fe4885b88059f170bfb7a4834132 Mon Sep 17 00:00:00 2001
From: Vivien Nicolas <21@vingtetun.org>
Date: Sun, 3 Jul 2011 22:29:46 +0200
Subject: [PATCH 7/9] Let Chrome (and others?) show TrueType fonts

---
 fonts.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fonts.js b/fonts.js
index ebbd0c0b8..12d7ce82e 100644
--- a/fonts.js
+++ b/fonts.js
@@ -905,7 +905,7 @@ var Font = (function () {
 
         // Tables needs to be written by ascendant alphabetic order
         tables.sort(function tables_sort(a, b) {
-          return a.tag > b.tag;
+          return (a.tag > b.tag) - (a.tag < b.tag);
         });
 
         // rewrite the tables but tweak offsets

From eb17d81316e8ba01a9d27d7263769995f13b93b5 Mon Sep 17 00:00:00 2001
From: Chris Jones <jones.chris.g@gmail.com>
Date: Mon, 4 Jul 2011 16:14:04 -0400
Subject: [PATCH 8/9] fix test.py bug on windows and stomped failure messages

---
 test/test.py         |  2 +-
 test/test_slave.html | 47 ++++++++++++++++++++++++--------------------
 2 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/test/test.py b/test/test.py
index 52e91476a..367347e88 100644
--- a/test/test.py
+++ b/test/test.py
@@ -99,7 +99,7 @@ class PDFTestHandler(BaseHTTPRequestHandler):
         self.send_header("Content-Type", MIMEs[ext])
         self.send_header("Content-Length", os.path.getsize(path))
         self.end_headers()
-        with open(path) as f:
+        with open(path, "rb") as f:
             self.wfile.write(f.read())
 
     def do_GET(self):
diff --git a/test/test_slave.html b/test/test_slave.html
index 3180418fa..0bf254ad5 100644
--- a/test/test_slave.html
+++ b/test/test_slave.html
@@ -88,31 +88,35 @@ function nextPage() {
     }
   }
 
-  failure = '';
-  log("    loading page "+ currentTask.pageNum +"... ");
+  var ctx, fonts, gfx;
+  if (!failure) {
+    log("    loading page "+ currentTask.pageNum +"... ");
 
-  var ctx = canvas.getContext("2d");
+    ctx = canvas.getContext("2d");
 
-  var fonts = [];
-  var gfx = null;
-  try {
-    gfx = new CanvasGraphics(ctx);
-    currentPage = pdfDoc.getPage(currentTask.pageNum);
-    currentPage.compile(gfx, fonts);
-  } catch(e) {
-    failure = 'compile: '+ e.toString();
+    fonts = [];
+    gfx = null;
+    try {
+      gfx = new CanvasGraphics(ctx);
+      currentPage = pdfDoc.getPage(currentTask.pageNum);
+      currentPage.compile(gfx, fonts);
+    } catch(e) {
+      failure = 'compile: '+ e.toString();
+    }
   }
 
-  try {
-    var pdfToCssUnitsCoef = 96.0 / 72.0;
-    // using mediaBox for the canvas size
-    var pageWidth = (currentPage.mediaBox[2] - currentPage.mediaBox[0]);
-    var pageHeight = (currentPage.mediaBox[3] - currentPage.mediaBox[1]);
-    canvas.width = pageWidth * pdfToCssUnitsCoef;
-    canvas.height = pageHeight * pdfToCssUnitsCoef;
-    clear(ctx);
-  } catch(e) {
-    failure = 'page setup: '+ e.toString();
+  if (!failure) {
+    try {
+      var pdfToCssUnitsCoef = 96.0 / 72.0;
+      // using mediaBox for the canvas size
+      var pageWidth = (currentPage.mediaBox[2] - currentPage.mediaBox[0]);
+      var pageHeight = (currentPage.mediaBox[3] - currentPage.mediaBox[1]);
+      canvas.width = pageWidth * pdfToCssUnitsCoef;
+      canvas.height = pageHeight * pdfToCssUnitsCoef;
+      clear(ctx);
+    } catch(e) {
+      failure = 'page setup: '+ e.toString();
+    }
   }
 
   if (!failure) {
@@ -145,6 +149,7 @@ function snapshotCurrentPage(gfx) {
   log("done"+ (failure ? " (failed!)" : "") +"\n");
 
   // Set up the next request
+  failure = '';
   backoff = (inFlightRequests > 0) ? inFlightRequests * 10 : 0;
   setTimeout(function() {
       ++currentTask.pageNum, nextPage();

From d4f49c05c5f4fbaeda24ec5b7b590ce36434a74d Mon Sep 17 00:00:00 2001
From: Chris Jones <jones.chris.g@gmail.com>
Date: Mon, 4 Jul 2011 17:39:29 -0400
Subject: [PATCH 9/9] fix another binary-mode issue

---
 pdf.js       | 1 +
 test/test.py | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/pdf.js b/pdf.js
index 814c99f75..48fa004e6 100644
--- a/pdf.js
+++ b/pdf.js
@@ -2971,6 +2971,7 @@ var Catalog = (function() {
 
 var PDFDoc = (function() {
     function constructor(stream) {
+        assertWellFormed(stream.length > 0, "stream must have data");
         this.stream = stream;
         this.setup();
     }
diff --git a/test/test.py b/test/test.py
index 367347e88..00b87f786 100644
--- a/test/test.py
+++ b/test/test.py
@@ -275,7 +275,7 @@ def downloadLinkedPDFs(manifestList):
             sys.stdout.flush()
             response = urllib2.urlopen(link)
 
-            with open(f, 'w') as out:
+            with open(f, 'wb') as out:
                 out.write(response.read())
 
             print 'done'