From d2f463bf7c1a912c9616a3c90c135d622c5da626 Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Wed, 21 Mar 2012 23:36:10 +0100
Subject: [PATCH 01/18] Add a progressbar to the loading indicator, below the
 text.

---
 web/viewer.css  | 20 +++++++++++++++++-
 web/viewer.html |  5 ++++-
 web/viewer.js   | 54 +++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 75 insertions(+), 4 deletions(-)

diff --git a/web/viewer.css b/web/viewer.css
index fdce0288a..536073c34 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -391,11 +391,29 @@ canvas {
   }
 }
 
-#loading {
+#loadingBox {
   margin: 100px 0;
   text-align: center;
 }
 
+#loadingBar {
+  display: inline-block;
+  border: 1px solid black;
+  clear: both;
+  padding: 1px;
+  margin:0px;
+}
+
+#loadingBar #progress {
+  background-color: green;
+  display: inline-block;
+}
+
+#loadingBar #remaining {
+  background-color: #333;
+  display: inline-block;
+}
+
 #PDFBug {
   font-size: 10px;
   position: fixed;
diff --git a/web/viewer.html b/web/viewer.html
index 34b2e77cb..b30b52db9 100644
--- a/web/viewer.html
+++ b/web/viewer.html
@@ -142,7 +142,10 @@
       </div>
     </div>
 
-    <div id="loading">Loading... 0%</div>
+    <div id="loadingBox">
+        <div id="loading">Loading... 0%</div>
+        <div id="loadingBar"><div id="progress"></div><div id="remaining"></div></div>
+    </div>
     <div id="viewer"></div>
   </body>
 </html>
diff --git a/web/viewer.js b/web/viewer.js
index 67ef67e97..b8d7b44f0 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -27,6 +27,49 @@ var Cache = function cacheCache(size) {
   };
 };
 
+var ProgressBar = (function ProgressBarClosure() {
+
+    function clamp(v, min, max) {
+        return Math.min(Math.max(v, min), max);
+    }
+    
+    function sizeBar(bar, num, width, height, units) {
+        var progress = bar.querySelector('#progress');
+        var remaining = bar.querySelector('#remaining');
+        progress.style.height=height + units;
+        remaining.style.height=height + units;
+        progress.style.width=num + units;
+        remaining.style.width=(width - num) + units;
+    }
+
+    function ProgressBar(element, min, max, width, height, units) {
+        this.element = element;
+        this.min = min;
+        this.max = max;
+        this.width = width;
+        this.height = height;
+        this.units = units;
+        this.value = min;
+        sizeBar(element, 0, this.width, this.height, this.units);
+    }
+
+    ProgressBar.prototype = {
+        constructor: ProgressBar,
+
+        get value() {
+            return this._value;
+        },
+
+        set value(val) {
+            this._value = clamp(val, this.min, this.max);
+            var num = this.width * (val - this.min) / (this.max - this.min);
+            sizeBar(this.element, num, this.width, this.height, this.units);
+        }
+    };
+
+    return ProgressBar;
+})();
+
 var RenderingQueue = (function RenderingQueueClosure() {
   function RenderingQueue() {
     this.items = [];
@@ -260,6 +303,11 @@ var PDFView = {
   open: function pdfViewOpen(url, scale) {
     document.title = this.url = url;
 
+    // FIXME: Probably needs a better place to get initialized
+    if(!PDFView.loadingProgress) {
+      PDFView.loadingProgress = new ProgressBar(document.getElementById('loadingBar'), 0, 100, 15, 1.5, 'em');
+    }
+
     var self = this;
     PDFJS.getPdf(
       {
@@ -400,6 +448,8 @@ var PDFView = {
     var percent = Math.round(level * 100);
     var loadingIndicator = document.getElementById('loading');
     loadingIndicator.textContent = 'Loading... ' + percent + '%';
+
+    PDFView.loadingProgress.value = percent;
   },
 
   load: function pdfViewLoad(data, scale) {
@@ -414,8 +464,8 @@ var PDFView = {
     var errorWrapper = document.getElementById('errorWrapper');
     errorWrapper.setAttribute('hidden', 'true');
 
-    var loadingIndicator = document.getElementById('loading');
-    loadingIndicator.setAttribute('hidden', 'true');
+    var loadingBox = document.getElementById('loadingBox');
+    loadingBox.setAttribute('hidden', 'true');
 
     var sidebar = document.getElementById('sidebarView');
     sidebar.parentNode.scrollTop = 0;

From ce8b0625b18302e1a29a0d7e256e18d6f80d99db Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Wed, 21 Mar 2012 23:56:20 +0100
Subject: [PATCH 02/18] Cosmetic changes

---
 web/viewer.css | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/web/viewer.css b/web/viewer.css
index 536073c34..eac80da84 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -401,12 +401,17 @@ canvas {
   border: 1px solid black;
   clear: both;
   padding: 1px;
-  margin:0px;
+  line-height: 0;
 }
 
 #loadingBar #progress {
-  background-color: green;
   display: inline-block;
+  background: -moz-linear-gradient(top, #b4e391 0%, #61c419 50%, #b4e391 100%);
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b4e391), color-stop(50%,#61c419), color-stop(100%,#b4e391));
+  background: -webkit-linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
+  background: -o-linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
+  background: -ms-linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
+  background: linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);  
 }
 
 #loadingBar #remaining {

From ecaf467a1396c9e91732eba5f16ff36c702607ae Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Thu, 22 Mar 2012 00:05:24 +0100
Subject: [PATCH 03/18] One more cosmetic tweak and fix 'make lint' complaints.

---
 web/viewer.css |  1 -
 web/viewer.js  | 16 +++++++++-------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/web/viewer.css b/web/viewer.css
index eac80da84..b316ddcb5 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -400,7 +400,6 @@ canvas {
   display: inline-block;
   border: 1px solid black;
   clear: both;
-  padding: 1px;
   line-height: 0;
 }
 
diff --git a/web/viewer.js b/web/viewer.js
index b8d7b44f0..246577a52 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -32,14 +32,14 @@ var ProgressBar = (function ProgressBarClosure() {
     function clamp(v, min, max) {
         return Math.min(Math.max(v, min), max);
     }
-    
+
     function sizeBar(bar, num, width, height, units) {
         var progress = bar.querySelector('#progress');
         var remaining = bar.querySelector('#remaining');
-        progress.style.height=height + units;
-        remaining.style.height=height + units;
-        progress.style.width=num + units;
-        remaining.style.width=(width - num) + units;
+        progress.style.height = height + units;
+        remaining.style.height = height + units;
+        progress.style.width = num + units;
+        remaining.style.width = (width - num) + units;
     }
 
     function ProgressBar(element, min, max, width, height, units) {
@@ -304,8 +304,10 @@ var PDFView = {
     document.title = this.url = url;
 
     // FIXME: Probably needs a better place to get initialized
-    if(!PDFView.loadingProgress) {
-      PDFView.loadingProgress = new ProgressBar(document.getElementById('loadingBar'), 0, 100, 15, 1.5, 'em');
+    if (!PDFView.loadingProgress) {
+      PDFView.loadingProgress = new ProgressBar(
+            document.getElementById('loadingBar'),
+            0, 100, 15, 1.5, 'em');
     }
 
     var self = this;

From 114d2c9ebd806f1aaab2029211bcf159cef5266a Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Thu, 22 Mar 2012 22:51:10 +0100
Subject: [PATCH 04/18] Simplified ProgressBar class. Visual tweaks.

---
 web/viewer.css  | 16 +++++++--
 web/viewer.html |  2 +-
 web/viewer.js   | 87 +++++++++++++++++++++++++------------------------
 3 files changed, 59 insertions(+), 46 deletions(-)

diff --git a/web/viewer.css b/web/viewer.css
index b316ddcb5..e8e986804 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -400,22 +400,32 @@ canvas {
   display: inline-block;
   border: 1px solid black;
   clear: both;
+  margin:0px;
   line-height: 0;
+  border-radius: 4px;
 }
 
-#loadingBar #progress {
+#loadingBar .progress {
+  background-color: green;
   display: inline-block;
+  
+  background: #b4e391;
   background: -moz-linear-gradient(top, #b4e391 0%, #61c419 50%, #b4e391 100%);
   background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b4e391), color-stop(50%,#61c419), color-stop(100%,#b4e391));
   background: -webkit-linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
   background: -o-linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
   background: -ms-linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);
-  background: linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);  
+  background: linear-gradient(top, #b4e391 0%,#61c419 50%,#b4e391 100%);    
+
+  border-top-left-radius: 3px;
+  border-bottom-left-radius: 3px;
 }
 
-#loadingBar #remaining {
+#loadingBar .remaining {
   background-color: #333;
   display: inline-block;
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 3px;
 }
 
 #PDFBug {
diff --git a/web/viewer.html b/web/viewer.html
index b30b52db9..6528d484f 100644
--- a/web/viewer.html
+++ b/web/viewer.html
@@ -144,7 +144,7 @@
 
     <div id="loadingBox">
         <div id="loading">Loading... 0%</div>
-        <div id="loadingBar"><div id="progress"></div><div id="remaining"></div></div>
+        <div id="loadingBar"><div class="progress"></div><div class="remaining"></div></div>
     </div>
     <div id="viewer"></div>
   </body>
diff --git a/web/viewer.js b/web/viewer.js
index 246577a52..ad24bc0a7 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -29,45 +29,49 @@ var Cache = function cacheCache(size) {
 
 var ProgressBar = (function ProgressBarClosure() {
 
-    function clamp(v, min, max) {
-        return Math.min(Math.max(v, min), max);
+  function clamp(v, min, max) {
+    return Math.min(Math.max(v, min), max);
+  }
+
+  function ProgressBar(id, opts) {
+
+    // Fetch the sub-elements for later
+    this.progressDiv = document.querySelector(id + ' .progress');
+    this.remainingDiv = document.querySelector(id + ' .remaining');
+
+    // Get options, with sensible defaults
+    this.height = opts.height || 1;
+    this.width = opts.width || 15;
+    this.units = opts.units || 'em';
+    this.percent = opts.progress || 0;
+
+    // Initialize heights
+    this.progressDiv.style.height = this.height + this.units;
+    this.remainingDiv.style.height = this.height + this.units;
+  }
+
+  ProgressBar.prototype = {
+    constructor: ProgressBar,
+
+    updateBar: function ProgressBar_updateBar() {
+      var progressSize = this.width * this._percent / 100;
+      var remainingSize = (this.width - progressSize);
+
+      this.progressDiv.style.width = progressSize + this.units;
+      this.remainingDiv.style.width = remainingSize + this.units;
+    },
+
+    get percent() {
+      return this._percent;
+    },
+
+    set percent(val) {
+      this._percent = clamp(val, 0, 100);
+      this.updateBar();
     }
+  };
 
-    function sizeBar(bar, num, width, height, units) {
-        var progress = bar.querySelector('#progress');
-        var remaining = bar.querySelector('#remaining');
-        progress.style.height = height + units;
-        remaining.style.height = height + units;
-        progress.style.width = num + units;
-        remaining.style.width = (width - num) + units;
-    }
-
-    function ProgressBar(element, min, max, width, height, units) {
-        this.element = element;
-        this.min = min;
-        this.max = max;
-        this.width = width;
-        this.height = height;
-        this.units = units;
-        this.value = min;
-        sizeBar(element, 0, this.width, this.height, this.units);
-    }
-
-    ProgressBar.prototype = {
-        constructor: ProgressBar,
-
-        get value() {
-            return this._value;
-        },
-
-        set value(val) {
-            this._value = clamp(val, this.min, this.max);
-            var num = this.width * (val - this.min) / (this.max - this.min);
-            sizeBar(this.element, num, this.width, this.height, this.units);
-        }
-    };
-
-    return ProgressBar;
+  return ProgressBar;
 })();
 
 var RenderingQueue = (function RenderingQueueClosure() {
@@ -304,10 +308,9 @@ var PDFView = {
     document.title = this.url = url;
 
     // FIXME: Probably needs a better place to get initialized
-    if (!PDFView.loadingProgress) {
-      PDFView.loadingProgress = new ProgressBar(
-            document.getElementById('loadingBar'),
-            0, 100, 15, 1.5, 'em');
+    if (!PDFView.loadingBar) {
+      PDFView.loadingBar = new ProgressBar('#loadingBar', {
+        width: 15, height: 1.5, units: 'em'});
     }
 
     var self = this;
@@ -451,7 +454,7 @@ var PDFView = {
     var loadingIndicator = document.getElementById('loading');
     loadingIndicator.textContent = 'Loading... ' + percent + '%';
 
-    PDFView.loadingProgress.value = percent;
+    PDFView.loadingBar.percent = percent;
   },
 
   load: function pdfViewLoad(data, scale) {

From ddf3d114d09a921af3ed626301e2da50574bbc6d Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Thu, 22 Mar 2012 22:57:42 +0100
Subject: [PATCH 05/18] Wrong word.

---
 web/viewer.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/web/viewer.js b/web/viewer.js
index ad24bc0a7..3f6fef957 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -43,7 +43,7 @@ var ProgressBar = (function ProgressBarClosure() {
     this.height = opts.height || 1;
     this.width = opts.width || 15;
     this.units = opts.units || 'em';
-    this.percent = opts.progress || 0;
+    this.percent = opts.percent || 0;
 
     // Initialize heights
     this.progressDiv.style.height = this.height + this.units;

From 536519a9a15483e6cc9ef0ab5535528b729743fd Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Fri, 23 Mar 2012 16:26:06 +0100
Subject: [PATCH 06/18] Assign the filename to the page title instead of the
 full URL

---
 web/viewer.js | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/web/viewer.js b/web/viewer.js
index 67ef67e97..73a65ca05 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -258,7 +258,9 @@ var PDFView = {
   },
 
   open: function pdfViewOpen(url, scale) {
-    document.title = this.url = url;
+    this.url = url;
+
+    document.title = (url.substring(url.lastIndexOf('/')+1)) || url;
 
     var self = this;
     PDFJS.getPdf(

From 080a80b7161704d12c8584b00a032a7d7ac60cd4 Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Fri, 23 Mar 2012 21:13:04 +0100
Subject: [PATCH 07/18] Better filename cleanup

---
 web/viewer.js | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/web/viewer.js b/web/viewer.js
index 73a65ca05..6d3b13cdf 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -15,6 +15,18 @@ var kMaxScale = 4.0;
 var kImageDirectory = './images/';
 var kSettingsMemory = 20;
 
+var Util = {
+  getFileName: function Util_getFileName(url) {
+    var anchor = url.indexOf("#");
+    var query = url.indexOf("?");
+    var s = url.lastIndexOf("/") + 1;
+    var e = url.length;
+    if (anchor > 0) e=Math.min(anchor,e);
+    if (query > 0) e=Math.min(query,e);
+    return url.substring(url.lastIndexOf("/") + 1, e);
+  }
+};
+
 var Cache = function cacheCache(size) {
   var data = [];
   this.push = function cachePush(view) {
@@ -260,7 +272,7 @@ var PDFView = {
   open: function pdfViewOpen(url, scale) {
     this.url = url;
 
-    document.title = (url.substring(url.lastIndexOf('/')+1)) || url;
+    document.title = Util.getFileName(url) || url;
 
     var self = this;
     PDFJS.getPdf(

From ab46530ff81e09565c129eef1f09970b3584f7d8 Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Sat, 24 Mar 2012 15:23:27 +0100
Subject: [PATCH 08/18] Lint fixes.

---
 web/viewer.js | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/web/viewer.js b/web/viewer.js
index 6d3b13cdf..83fc06544 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -17,13 +17,12 @@ var kSettingsMemory = 20;
 
 var Util = {
   getFileName: function Util_getFileName(url) {
-    var anchor = url.indexOf("#");
-    var query = url.indexOf("?");
-    var s = url.lastIndexOf("/") + 1;
-    var e = url.length;
-    if (anchor > 0) e=Math.min(anchor,e);
-    if (query > 0) e=Math.min(query,e);
-    return url.substring(url.lastIndexOf("/") + 1, e);
+    var anchor = url.indexOf('#');
+    var query = url.indexOf('?');
+    var end = url.length;
+    if (anchor > 0) end = Math.min(anchor, end);
+    if (query > 0) end = Math.min(query, end);
+    return url.substring(url.lastIndexOf('/') + 1, end);
   }
 };
 

From 72355121a0933b384718096ebe638cf0df786933 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Sun, 25 Mar 2012 14:15:40 -0500
Subject: [PATCH 09/18] Don't print missing symbols in the font

---
 src/canvas.js |  2 ++
 src/fonts.js  | 29 +++++++++++++++++++++--------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/canvas.js b/src/canvas.js
index 7bf94a642..2528a6b3b 100644
--- a/src/canvas.js
+++ b/src/canvas.js
@@ -751,6 +751,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
             x += Util.sign(current.fontMatrix[0]) * wordSpacing;
             continue;
           }
+          if (glyph.disabled)
+            continue;
 
           var char = glyph.fontChar;
           var charWidth = glyph.width * fontSize * 0.001 +
diff --git a/src/fonts.js b/src/fonts.js
index 500ef8780..5d63d7c50 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -1828,8 +1828,9 @@ var Font = (function FontClosure() {
         readGlyphNameMap(post, properties);
       }
 
-      // Replace the old CMAP table with a shiny new one
+      var glyphs, ids;
       if (properties.type == 'CIDFontType2') {
+        // Replace the old CMAP table with a shiny new one
         // Type2 composite fonts map characters directly to glyphs so the cmap
         // table must be replaced.
         // canvas fillText will reencode some characters even if the font has a
@@ -1861,7 +1862,9 @@ var Font = (function FontClosure() {
           }
         }
 
-        var glyphs = [], ids = [];
+        glyphs = [];
+        ids = [];
+
         var usedUnicodes = [];
         var unassignedUnicodeItems = [];
         for (var i = 1; i < numGlyphs; i++) {
@@ -1892,11 +1895,12 @@ var Font = (function FontClosure() {
           glyphs.push({ unicode: unicode, code: cid });
           ids.push(i);
         }
-        cmap.data = createCMapTable(glyphs, ids);
       } else {
         var cmapTable = readCMapTable(cmap, font);
-        var glyphs = cmapTable.glyphs;
-        var ids = cmapTable.ids;
+
+        glyphs = cmapTable.glyphs;
+        ids = cmapTable.ids;
+
         var hasShortCmap = !!cmapTable.hasShortCmap;
         var toFontChar = this.toFontChar;
 
@@ -2049,10 +2053,16 @@ var Font = (function FontClosure() {
 
         createGlyphNameMap(glyphs, ids, properties);
         this.glyphNameMap = properties.glyphNameMap;
-
-        cmap.data = createCMapTable(glyphs, ids);
       }
 
+      // Converting glyphs and ids into font's cmap table
+      cmap.data = createCMapTable(glyphs, ids);
+      var unicodeIsEnabled = [];
+      for (var i = 0, ii = glyphs.length; i < ii; i++) {
+        unicodeIsEnabled[glyphs[i].unicode] = true;
+      }
+      this.unicodeIsEnabled = unicodeIsEnabled;
+
       // Rewrite the 'post' table if needed
       if (requiredTables.indexOf('post') != -1) {
         tables.push({
@@ -2378,7 +2388,7 @@ var Font = (function FontClosure() {
     },
 
     charToGlyph: function fonts_charToGlyph(charcode) {
-      var fontCharCode, width, operatorList;
+      var fontCharCode, width, operatorList, disabled;
 
       var width = this.widths[charcode];
 
@@ -2451,11 +2461,14 @@ var Font = (function FontClosure() {
         unicodeChars = String.fromCharCode(unicodeChars);
 
       width = (isNum(width) ? width : this.defaultWidth) * this.widthMultiplier;
+      disabled = this.unicodeIsEnabled ?
+        !this.unicodeIsEnabled[fontCharCode] : false;
 
       return {
         fontChar: String.fromCharCode(fontCharCode),
         unicode: unicodeChars,
         width: width,
+        disabled: disabled,
         operatorList: operatorList
       };
     },

From bcdf7b46c58bbd573efe00ce242dab50899908a7 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Sun, 25 Mar 2012 14:31:28 -0500
Subject: [PATCH 10/18] Fixing advance after disabled symbols

---
 src/canvas.js | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/canvas.js b/src/canvas.js
index 2528a6b3b..e915c4a84 100644
--- a/src/canvas.js
+++ b/src/canvas.js
@@ -751,31 +751,31 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
             x += Util.sign(current.fontMatrix[0]) * wordSpacing;
             continue;
           }
-          if (glyph.disabled)
-            continue;
 
           var char = glyph.fontChar;
           var charWidth = glyph.width * fontSize * 0.001 +
               Util.sign(current.fontMatrix[0]) * charSpacing;
 
-          var scaledX = x / fontSizeScale;
-          switch (textRenderingMode) {
-            default: // other unsupported rendering modes
-            case TextRenderingMode.FILL:
-            case TextRenderingMode.FILL_ADD_TO_PATH:
-              ctx.fillText(char, scaledX, 0);
-              break;
-            case TextRenderingMode.STROKE:
-            case TextRenderingMode.STROKE_ADD_TO_PATH:
-              ctx.strokeText(char, scaledX, 0);
-              break;
-            case TextRenderingMode.FILL_STROKE:
-            case TextRenderingMode.FILL_STROKE_ADD_TO_PATH:
-              ctx.fillText(char, scaledX, 0);
-              ctx.strokeText(char, scaledX, 0);
-              break;
-            case TextRenderingMode.INVISIBLE:
-              break;
+          if (!glyph.disabled) {
+            var scaledX = x / fontSizeScale;
+            switch (textRenderingMode) {
+              default: // other unsupported rendering modes
+              case TextRenderingMode.FILL:
+              case TextRenderingMode.FILL_ADD_TO_PATH:
+                ctx.fillText(char, scaledX, 0);
+                break;
+              case TextRenderingMode.STROKE:
+              case TextRenderingMode.STROKE_ADD_TO_PATH:
+                ctx.strokeText(char, scaledX, 0);
+                break;
+              case TextRenderingMode.FILL_STROKE:
+              case TextRenderingMode.FILL_STROKE_ADD_TO_PATH:
+                ctx.fillText(char, scaledX, 0);
+                ctx.strokeText(char, scaledX, 0);
+                break;
+              case TextRenderingMode.INVISIBLE:
+                break;
+            }
           }
 
           x += charWidth;

From a094dd4746ad4572d5c0aa321cdf290066bcadc0 Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Tue, 27 Mar 2012 09:13:32 +0200
Subject: [PATCH 11/18] Simplified the ProgressBar a bit: made the div
 fixed-size, removed the unnecessary '.remaining' div, used percent size for
 the '.progress' div.

---
 web/viewer.css  | 14 +++++++-------
 web/viewer.html |  2 +-
 web/viewer.js   | 21 +++++++--------------
 3 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/web/viewer.css b/web/viewer.css
index e8e986804..9a0cf388c 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -397,18 +397,22 @@ canvas {
 }
 
 #loadingBar {
+  background-color: #333;
   display: inline-block;
   border: 1px solid black;
   clear: both;
   margin:0px;
   line-height: 0;
   border-radius: 4px;
+  width: 15em;
+  height: 1.5em;
 }
 
 #loadingBar .progress {
   background-color: green;
   display: inline-block;
-  
+  float: left;
+
   background: #b4e391;
   background: -moz-linear-gradient(top, #b4e391 0%, #61c419 50%, #b4e391 100%);
   background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b4e391), color-stop(50%,#61c419), color-stop(100%,#b4e391));
@@ -419,13 +423,9 @@ canvas {
 
   border-top-left-radius: 3px;
   border-bottom-left-radius: 3px;
-}
 
-#loadingBar .remaining {
-  background-color: #333;
-  display: inline-block;
-  border-top-right-radius: 3px;
-  border-bottom-right-radius: 3px;
+  width: 0%;
+  height: 100%;
 }
 
 #PDFBug {
diff --git a/web/viewer.html b/web/viewer.html
index 6528d484f..8b59e4ebf 100644
--- a/web/viewer.html
+++ b/web/viewer.html
@@ -144,7 +144,7 @@
 
     <div id="loadingBox">
         <div id="loading">Loading... 0%</div>
-        <div id="loadingBar"><div class="progress"></div><div class="remaining"></div></div>
+        <div id="loadingBar"><div class="progress"></div></div>
     </div>
     <div id="viewer"></div>
   </body>
diff --git a/web/viewer.js b/web/viewer.js
index 3f6fef957..49a6cd4a3 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -36,29 +36,24 @@ var ProgressBar = (function ProgressBarClosure() {
   function ProgressBar(id, opts) {
 
     // Fetch the sub-elements for later
-    this.progressDiv = document.querySelector(id + ' .progress');
-    this.remainingDiv = document.querySelector(id + ' .remaining');
+    this.div = document.querySelector(id + ' .progress');
 
     // Get options, with sensible defaults
-    this.height = opts.height || 1;
-    this.width = opts.width || 15;
-    this.units = opts.units || 'em';
+    this.height = opts.height || 100;
+    this.width = opts.width || 100;
+    this.units = opts.units || '%';
     this.percent = opts.percent || 0;
 
     // Initialize heights
-    this.progressDiv.style.height = this.height + this.units;
-    this.remainingDiv.style.height = this.height + this.units;
+    this.div.style.height = this.height + this.units;
   }
 
   ProgressBar.prototype = {
-    constructor: ProgressBar,
 
     updateBar: function ProgressBar_updateBar() {
       var progressSize = this.width * this._percent / 100;
-      var remainingSize = (this.width - progressSize);
 
-      this.progressDiv.style.width = progressSize + this.units;
-      this.remainingDiv.style.width = remainingSize + this.units;
+      this.div.style.width = progressSize + this.units;
     },
 
     get percent() {
@@ -307,10 +302,8 @@ var PDFView = {
   open: function pdfViewOpen(url, scale) {
     document.title = this.url = url;
 
-    // FIXME: Probably needs a better place to get initialized
     if (!PDFView.loadingBar) {
-      PDFView.loadingBar = new ProgressBar('#loadingBar', {
-        width: 15, height: 1.5, units: 'em'});
+      PDFView.loadingBar = new ProgressBar('#loadingBar', {});
     }
 
     var self = this;

From 3280a2bececf4cc121aaf25d21cf26cc3ecf7a7c Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Tue, 27 Mar 2012 09:27:54 +0200
Subject: [PATCH 12/18] Unwrap getFileName from the object, avoid issues with /
 in query/anchor strings, simplify the code to calculate 'end'.

---
 web/viewer.js | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/web/viewer.js b/web/viewer.js
index 83fc06544..389eee6ab 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -15,16 +15,14 @@ var kMaxScale = 4.0;
 var kImageDirectory = './images/';
 var kSettingsMemory = 20;
 
-var Util = {
-  getFileName: function Util_getFileName(url) {
-    var anchor = url.indexOf('#');
-    var query = url.indexOf('?');
-    var end = url.length;
-    if (anchor > 0) end = Math.min(anchor, end);
-    if (query > 0) end = Math.min(query, end);
-    return url.substring(url.lastIndexOf('/') + 1, end);
-  }
-};
+function getFileName(url) {
+  var anchor = url.indexOf('#');
+  var query = url.indexOf('?');
+  var end = Math.min(
+    anchor > 0 ? anchor : url.length,
+    query > 0 ? query : url.length);
+  return url.substring(url.lastIndexOf('/', end) + 1, end);
+}
 
 var Cache = function cacheCache(size) {
   var data = [];
@@ -271,7 +269,7 @@ var PDFView = {
   open: function pdfViewOpen(url, scale) {
     this.url = url;
 
-    document.title = Util.getFileName(url) || url;
+    document.title = getFileName(url) || url;
 
     var self = this;
     PDFJS.getPdf(

From 8c5d33c86b478d6c7e27fedccc5c16411e269f58 Mon Sep 17 00:00:00 2001
From: Brendan Dahl <brendan.dahl@gmail.com>
Date: Thu, 29 Mar 2012 15:37:40 -0700
Subject: [PATCH 13/18] Fix cff regression.

---
 src/fonts.js                 | 10 ++++++----
 test/pdfs/issue1422.pdf.link |  1 +
 test/test_manifest.json      |  8 ++++++++
 3 files changed, 15 insertions(+), 4 deletions(-)
 create mode 100644 test/pdfs/issue1422.pdf.link

diff --git a/src/fonts.js b/src/fonts.js
index b756ff2ee..96fb7fabe 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -4362,16 +4362,18 @@ var CFFCompiler = (function CFFCompilerClosure() {
       output.add(charStrings);
 
       if (cff.isCIDFont) {
+        // For some reason FDSelect must be in front of FDArray on windows. OSX
+        // and linux don't seem to care.
+        topDictTracker.setEntryLocation('FDSelect', [output.length], output);
+        var fdSelect = this.compileFDSelect(cff.fdSelect.raw);
+        output.add(fdSelect);
+
         var compiled = this.compileTopDicts(cff.fdArray, output.length);
         topDictTracker.setEntryLocation('FDArray', [output.length], output);
         output.add(compiled.output);
         var fontDictTrackers = compiled.trackers;
 
         this.compilePrivateDicts(cff.fdArray, fontDictTrackers, output);
-
-        topDictTracker.setEntryLocation('FDSelect', [output.length], output);
-        var fdSelect = this.compileFDSelect(cff.fdSelect.raw);
-        output.add(fdSelect);
       }
 
       this.compilePrivateDicts([cff.topDict], [topDictTracker], output);
diff --git a/test/pdfs/issue1422.pdf.link b/test/pdfs/issue1422.pdf.link
new file mode 100644
index 000000000..9f2ba3d45
--- /dev/null
+++ b/test/pdfs/issue1422.pdf.link
@@ -0,0 +1 @@
+http://www.cpi.si/files/cpi/userfiles/TrajnostniRazvoj/06_Prosti_cas.pdf
diff --git a/test/test_manifest.json b/test/test_manifest.json
index a4c6defcc..6459834cd 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -558,5 +558,13 @@
       "rounds": 1,
       "link": true,
       "type": "eq"
+    },
+    {  "id": "issue1422",
+      "file": "pdfs/issue1422.pdf",
+      "md5": "f7a732a86960b330b8108d5cdece19e3",
+      "rounds": 1,
+      "pageLimit": 1,
+      "link": true,
+      "type": "eq"
     }
 ]

From b6d23ac9dc0215306918627165b6dbd72f6f2549 Mon Sep 17 00:00:00 2001
From: Brendan Dahl <brendan.dahl@gmail.com>
Date: Fri, 30 Mar 2012 09:12:46 -0700
Subject: [PATCH 14/18] Remove test case, already covered.

---
 test/pdfs/issue1422.pdf.link | 1 -
 test/test_manifest.json      | 8 --------
 2 files changed, 9 deletions(-)
 delete mode 100644 test/pdfs/issue1422.pdf.link

diff --git a/test/pdfs/issue1422.pdf.link b/test/pdfs/issue1422.pdf.link
deleted file mode 100644
index 9f2ba3d45..000000000
--- a/test/pdfs/issue1422.pdf.link
+++ /dev/null
@@ -1 +0,0 @@
-http://www.cpi.si/files/cpi/userfiles/TrajnostniRazvoj/06_Prosti_cas.pdf
diff --git a/test/test_manifest.json b/test/test_manifest.json
index 6459834cd..a4c6defcc 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -558,13 +558,5 @@
       "rounds": 1,
       "link": true,
       "type": "eq"
-    },
-    {  "id": "issue1422",
-      "file": "pdfs/issue1422.pdf",
-      "md5": "f7a732a86960b330b8108d5cdece19e3",
-      "rounds": 1,
-      "pageLimit": 1,
-      "link": true,
-      "type": "eq"
     }
 ]

From c6d7e654ee19a18a6029ac353441bc4024b548f8 Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Fri, 30 Mar 2012 23:17:04 +0200
Subject: [PATCH 15/18] Replace variables named 'char'=>'character',
 'byte'=>'octet' and field '.private'=>'.privateData'. This allows pdf.js to
 compile with Google's Closure Compiler.

---
 src/canvas.js            | 10 ++---
 src/evaluator.js         | 12 +++---
 src/fonts.js             | 86 ++++++++++++++++++++--------------------
 src/image.js             |  4 +-
 src/obj.js               |  4 +-
 src/parser.js            |  4 +-
 src/stream.js            |  6 +--
 src/utils/fonts_utils.js |  8 ++--
 8 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/src/canvas.js b/src/canvas.js
index e915c4a84..dd363ecf3 100644
--- a/src/canvas.js
+++ b/src/canvas.js
@@ -752,7 +752,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
             continue;
           }
 
-          var char = glyph.fontChar;
+          var character = glyph.fontChar;
           var charWidth = glyph.width * fontSize * 0.001 +
               Util.sign(current.fontMatrix[0]) * charSpacing;
 
@@ -762,16 +762,16 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
               default: // other unsupported rendering modes
               case TextRenderingMode.FILL:
               case TextRenderingMode.FILL_ADD_TO_PATH:
-                ctx.fillText(char, scaledX, 0);
+                ctx.fillText(character, scaledX, 0);
                 break;
               case TextRenderingMode.STROKE:
               case TextRenderingMode.STROKE_ADD_TO_PATH:
-                ctx.strokeText(char, scaledX, 0);
+                ctx.strokeText(character, scaledX, 0);
                 break;
               case TextRenderingMode.FILL_STROKE:
               case TextRenderingMode.FILL_STROKE_ADD_TO_PATH:
-                ctx.fillText(char, scaledX, 0);
-                ctx.strokeText(char, scaledX, 0);
+                ctx.fillText(character, scaledX, 0);
+                ctx.strokeText(character, scaledX, 0);
                 break;
               case TextRenderingMode.INVISIBLE:
                 break;
diff --git a/src/evaluator.js b/src/evaluator.js
index 0a4db37e8..05be3511c 100644
--- a/src/evaluator.js
+++ b/src/evaluator.js
@@ -536,9 +536,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
 
         var cmap = cmapObj.getBytes(cmapObj.length);
         for (var i = 0, ii = cmap.length; i < ii; i++) {
-          var byte = cmap[i];
-          if (byte == 0x20 || byte == 0x0D || byte == 0x0A ||
-              byte == 0x3C || byte == 0x5B || byte == 0x5D) {
+          var octet = cmap[i];
+          if (octet == 0x20 || octet == 0x0D || octet == 0x0A ||
+              octet == 0x3C || octet == 0x5B || octet == 0x5D) {
             switch (token) {
               case 'usecmap':
                 error('usecmap is not implemented');
@@ -595,7 +595,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
                 tokens.push(token);
                 token = '';
             }
-            switch (byte) {
+            switch (octet) {
               case 0x5B:
                 // begin list parsing
                 tokens.push(beginArrayToken);
@@ -609,7 +609,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
                 tokens.push(items);
                 break;
             }
-          } else if (byte == 0x3E) {
+          } else if (octet == 0x3E) {
             if (token.length) {
               if (token.length <= 4) {
                 // parsing hex number
@@ -635,7 +635,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
               }
             }
           } else {
-            token += String.fromCharCode(byte);
+            token += String.fromCharCode(octet);
           }
         }
       }
diff --git a/src/fonts.js b/src/fonts.js
index cdff1f980..66c3be0f6 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -390,7 +390,7 @@ var symbolsFonts = {
   'Dingbats': true, 'Symbol': true, 'ZapfDingbats': true
 };
 
-// Some characters, e.g. copyrightserif, mapped to the private use area and
+// Some characters, e.g. copyrightserif, mapped to the privateData use area and
 // might not be displayed using standard fonts. Mapping/hacking well-known chars
 // to the similar equivalents in the normal characters range.
 function mapPrivateUseChars(code) {
@@ -1216,7 +1216,7 @@ var Font = (function FontClosure() {
       'Unknown'            // 9.Designer
     ];
 
-    // Mac want 1-byte per character strings while Windows want
+    // Mac want 1-octet per character strings while Windows want
     // 2-bytes per character, so duplicate the names table
     var stringsUnicode = [];
     for (var i = 0, ii = strings.length; i < ii; i++) {
@@ -1970,7 +1970,7 @@ var Font = (function FontClosure() {
             minUnicode = Math.min(minUnicode, unicode);
             maxUnicode = Math.max(maxUnicode, unicode);
           }
-          // high byte must be the same for min and max unicodes
+          // high octet must be the same for min and max unicodes
           if ((maxUnicode & 0xFF00) != (minUnicode & 0xFF00))
             this.isSymbolicFont = false;
         }
@@ -1986,7 +1986,7 @@ var Font = (function FontClosure() {
         if (hasShortCmap && this.hasEncoding && !this.isSymbolicFont) {
           // Re-encode short map encoding to unicode -- that simplifies the
           // resolution of MacRoman encoded glyphs logic for TrueType fonts:
-          // copying all characters to private use area, all mapping all known
+          // copying all characters to privateData use area, all mapping all known
           // glyphs to the unicodes. The glyphs and ids arrays will grow.
           var usedUnicodes = [];
           for (var i = 0, ii = glyphs.length; i < ii; i++) {
@@ -2114,7 +2114,7 @@ var Font = (function FontClosure() {
         var tableData = table.data;
         ttf.file += arrayToString(tableData);
 
-        // 4-byte aligned data
+        // 4-octet aligned data
         while (ttf.file.length & 3)
           ttf.file += String.fromCharCode(0);
       }
@@ -2504,12 +2504,12 @@ var Font = (function FontClosure() {
       glyphs = [];
 
       if (this.composite) {
-        // composite fonts have multi-byte strings convert the string from
-        // single-byte to multi-byte
-        // XXX assuming CIDFonts are two-byte - later need to extract the
-        // correct byte encoding according to the PDF spec
+        // composite fonts have multi-octet strings convert the string from
+        // single-octet to multi-octet
+        // XXX assuming CIDFonts are two-octet - later need to extract the
+        // correct octet encoding according to the PDF spec
         var length = chars.length - 1; // looping over two bytes at a time so
-                                       // loop should never end on the last byte
+                                       // loop should never end on the last octet
         for (var i = 0; i < length; i++) {
           var charcode = int16([chars.charCodeAt(i++), chars.charCodeAt(i)]);
           var glyph = this.charToGlyph(charcode);
@@ -2568,37 +2568,37 @@ var Type1Parser = function type1Parser() {
   /*
    * CharStrings are encoded following the the CharString Encoding sequence
    * describe in Chapter 6 of the "Adobe Type1 Font Format" specification.
-   * The value in a byte indicates a command, a number, or subsequent bytes
+   * The value in a octet indicates a command, a number, or subsequent bytes
    * that are to be interpreted in a special way.
    *
    * CharString Number Encoding:
-   *  A CharString byte containing the values from 32 through 255 inclusive
+   *  A CharString octet containing the values from 32 through 255 inclusive
    *  indicate an integer. These values are decoded in four ranges.
    *
-   * 1. A CharString byte containing a value, v, between 32 and 246 inclusive,
+   * 1. A CharString octet containing a value, v, between 32 and 246 inclusive,
    * indicate the integer v - 139. Thus, the integer values from -107 through
-   * 107 inclusive may be encoded in single byte.
+   * 107 inclusive may be encoded in single octet.
    *
-   * 2. A CharString byte containing a value, v, between 247 and 250 inclusive,
-   * indicates an integer involving the next byte, w, according to the formula:
+   * 2. A CharString octet containing a value, v, between 247 and 250 inclusive,
+   * indicates an integer involving the next octet, w, according to the formula:
    * [(v - 247) x 256] + w + 108
    *
-   * 3. A CharString byte containing a value, v, between 251 and 254 inclusive,
-   * indicates an integer involving the next byte, w, according to the formula:
+   * 3. A CharString octet containing a value, v, between 251 and 254 inclusive,
+   * indicates an integer involving the next octet, w, according to the formula:
    * -[(v - 251) * 256] - w - 108
    *
    * 4. A CharString containing the value 255 indicates that the next 4 bytes
    * are a two complement signed integer. The first of these bytes contains the
-   * highest order bits, the second byte contains the next higher order bits
-   * and the fourth byte contain the lowest order bits.
+   * highest order bits, the second octet contains the next higher order bits
+   * and the fourth octet contain the lowest order bits.
    *
    *
    * CharString Command Encoding:
    *  CharStrings commands are encoded in 1 or 2 bytes.
    *
-   *  Single byte commands are encoded in 1 byte that contains a value between
+   *  Single octet commands are encoded in 1 octet that contains a value between
    *  0 and 31 inclusive.
-   *  If a command byte contains the value 12, then the value in the next byte
+   *  If a command octet contains the value 12, then the value in the next octet
    *  indicates a command. This "escape" mechanism allows many extra commands
    * to be encoded and this encoding technique helps to minimize the length of
    * the charStrings.
@@ -2861,7 +2861,7 @@ var Type1Parser = function type1Parser() {
       subrs: [],
       charstrings: [],
       properties: {
-        'private': {
+        'privateData': {
           'lenIV': 4
         }
       }
@@ -2890,7 +2890,7 @@ var Type1Parser = function type1Parser() {
           (token == 'RD' || token == '-|')) {
         i++;
         var data = eexec.slice(i, i + length);
-        var lenIV = program.properties.private['lenIV'];
+        var lenIV = program.properties.privateData['lenIV'];
         var encoded = decrypt(data, kCharStringsEncryptionKey, lenIV);
         var str = decodeCharString(encoded);
 
@@ -2930,7 +2930,7 @@ var Type1Parser = function type1Parser() {
                 var length = parseInt(getToken(), 10);
                 getToken(); // read in 'RD'
                 var data = eexec.slice(i + 1, i + 1 + length);
-                var lenIV = program.properties.private['lenIV'];
+                var lenIV = program.properties.privateData['lenIV'];
                 var encoded = decrypt(data, kCharStringsEncryptionKey, lenIV);
                 var str = decodeCharString(encoded);
                 i = i + 1 + length;
@@ -2946,12 +2946,12 @@ var Type1Parser = function type1Parser() {
             case '/FamilyOtherBlues':
             case '/StemSnapH':
             case '/StemSnapV':
-              program.properties.private[token.substring(1)] =
+              program.properties.privateData[token.substring(1)] =
                 readNumberArray(eexecStr, i + 1);
               break;
             case '/StdHW':
             case '/StdVW':
-              program.properties.private[token.substring(1)] =
+              program.properties.privateData[token.substring(1)] =
                 readNumberArray(eexecStr, i + 2)[0];
               break;
             case '/BlueShift':
@@ -2960,7 +2960,7 @@ var Type1Parser = function type1Parser() {
             case '/BlueScale':
             case '/LanguageGroup':
             case '/ExpansionFactor':
-              program.properties.private[token.substring(1)] =
+              program.properties.privateData[token.substring(1)] =
                 readNumber(eexecStr, i + 1);
               break;
           }
@@ -2984,14 +2984,14 @@ var Type1Parser = function type1Parser() {
     var count = headerString.length;
     for (var i = 0; i < count; i++) {
       var getToken = function getToken() {
-        var char = headerString[i];
-        while (i < count && (isSeparator(char) || char == '/'))
-          char = headerString[++i];
+        var character = headerString[i];
+        while (i < count && (isSeparator(character) || character == '/'))
+          character = headerString[++i];
 
         var token = '';
-        while (i < count && !(isSeparator(char) || char == '/')) {
-          token += char;
-          char = headerString[++i];
+        while (i < count && !(isSeparator(character) || character == '/')) {
+          token += character;
+          character = headerString[++i];
         }
 
         return token;
@@ -3148,13 +3148,13 @@ Type1Font.prototype = {
     var count = objects.length;
 
     // If there is no object, just create an array saying that with another
-    // offset byte.
+    // offset octet.
     if (count == 0)
       return '\x00\x00\x00';
 
     var data = String.fromCharCode((count >> 8) & 0xFF, count & 0xff);
 
-    // Next byte contains the offset size use to reference object in the file
+    // Next octet 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
     // without thinking of it while coding.
     data += '\x04';
@@ -3357,7 +3357,7 @@ Type1Font.prototype = {
           dict += self.encodeNumber(offset) + '\x11'; // Charstrings
 
           offset = offset + fields.charstrings.length;
-          dict += self.encodeNumber(fields.private.length);
+          dict += self.encodeNumber(fields.privateData.length);
           dict += self.encodeNumber(offset) + '\x12'; // Private
 
           return header + String.fromCharCode(dict.length + 1) + dict;
@@ -3398,7 +3398,7 @@ Type1Font.prototype = {
       'charstrings': this.createCFFIndexHeader([[0x8B, 0x0E]].concat(glyphs),
                                                true),
 
-      'private': (function cffWrapPrivate(self) {
+      'privateData': (function cffWrapPrivate(self) {
         var data =
             '\x8b\x14' + // defaultWidth
             '\x8b\x15';  // nominalWidth
@@ -3416,9 +3416,9 @@ Type1Font.prototype = {
           ExpansionFactor: '\x0c\x18'
         };
         for (var field in fieldMap) {
-          if (!properties.private.hasOwnProperty(field))
+          if (!properties.privateData.hasOwnProperty(field))
             continue;
-          var value = properties.private[field];
+          var value = properties.privateData[field];
 
           if (isArray(value)) {
             data += self.encodeNumber(value[0]);
@@ -3800,7 +3800,7 @@ var CFFParser = (function CFFParserClosure() {
       return charStrings;
     },
     parsePrivateDict: function parsePrivateDict(parentDict) {
-      // no private dict, do nothing
+      // no privateData dict, do nothing
       if (!parentDict.hasName('Private'))
         return;
       var privateOffset = parentDict.getByName('Private');
@@ -3824,7 +3824,7 @@ var CFFParser = (function CFFParserClosure() {
                                         parentDict.strings);
       parentDict.privateDict = privateDict;
 
-      // Parse the Subrs index also since it's relative to the private dict.
+      // Parse the Subrs index also since it's relative to the privateData dict.
       if (!privateDict.getByName('Subrs'))
         return;
       var subrsOffset = privateDict.getByName('Subrs');
@@ -4611,7 +4611,7 @@ var CFFCompiler = (function CFFCompilerClosure() {
       else
         offsetSize = 4;
 
-      // Next byte contains the offset size use to reference object in the file
+      // Next octet contains the offset size use to reference object in the file
       data.push(offsetSize);
 
       // Add another offset after this one because we need a new offset
diff --git a/src/image.js b/src/image.js
index 7c23a3426..22e79ba21 100644
--- a/src/image.js
+++ b/src/image.js
@@ -314,7 +314,7 @@ var PDFImage = (function PDFImageClosure() {
       var originalHeight = this.height;
       var bpc = this.bpc;
 
-      // rows start at byte boundary;
+      // rows start at octet boundary;
       var rowBytes = (originalWidth * numComps * bpc + 7) >> 3;
       var imgArray = this.getImageBytes(originalHeight * rowBytes);
 
@@ -344,7 +344,7 @@ var PDFImage = (function PDFImageClosure() {
       var height = this.height;
       var bpc = this.bpc;
 
-      // rows start at byte boundary;
+      // rows start at octet boundary;
       var rowBytes = (width * numComps * bpc + 7) >> 3;
       var imgArray = this.getImageBytes(height * rowBytes);
 
diff --git a/src/obj.js b/src/obj.js
index 2eb9c6f1d..cadc59127 100644
--- a/src/obj.js
+++ b/src/obj.js
@@ -438,7 +438,7 @@ var XRef = (function XRefClosure() {
       function skipUntil(data, offset, what) {
         var length = what.length, dataLength = data.length;
         var skipped = 0;
-        // finding byte sequence
+        // finding octet sequence
         while (offset < dataLength) {
           var i = 0;
           while (i < length && data[offset + i] == what[i])
@@ -494,7 +494,7 @@ var XRef = (function XRefClosure() {
           var content = buffer.subarray(position, position + contentLength);
 
           // checking XRef stream suspect
-          // (it shall have '/XRef' and next char is not a letter)
+          // (it shall have '/XRef' and next character is not a letter)
           var xrefTagOffset = skipUntil(content, 0, xrefBytes);
           if (xrefTagOffset < contentLength &&
               content[xrefTagOffset + 5] < 64) {
diff --git a/src/parser.js b/src/parser.js
index fad8b2c03..e2fcb056d 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -27,7 +27,7 @@ var Parser = (function ParserClosure() {
       if (isCmd(this.buf2, 'ID')) {
         this.buf1 = this.buf2;
         this.buf2 = null;
-        // skip byte after ID
+        // skip octet after ID
         this.lexer.skip();
       } else {
         this.buf1 = this.buf2;
@@ -424,7 +424,7 @@ var Lexer = (function LexerClosure() {
             stream.skip();
             var x2 = toHexDigit(stream.getChar());
             if (x2 == -1)
-              error('Illegal digit in hex char in name: ' + x2);
+              error('Illegal digit in hex character in name: ' + x2);
             str += String.fromCharCode((x << 4) | x2);
           } else {
             str += '#';
diff --git a/src/stream.js b/src/stream.js
index d31f3d50b..6911b7163 100644
--- a/src/stream.js
+++ b/src/stream.js
@@ -1162,10 +1162,10 @@ var RunLengthStream = (function RunLengthStreamClosure() {
   RunLengthStream.prototype = Object.create(DecodeStream.prototype);
 
   RunLengthStream.prototype.readBlock = function runLengthStreamReadBlock() {
-    // The repeatHeader has following format. The first byte defines type of run
+    // The repeatHeader has following format. The first octet defines type of run
     // and amount of bytes to repeat/copy: n = 0 through 127 - copy next n bytes
-    // (in addition to the second byte from the header), n = 129 through 255 -
-    // duplicate the second byte from the header (257 - n) times, n = 128 - end.
+    // (in addition to the second octet from the header), n = 129 through 255 -
+    // duplicate the second octet from the header (257 - n) times, n = 128 - end.
     var repeatHeader = this.str.getBytes(2);
     if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] == 128) {
       this.eof = true;
diff --git a/src/utils/fonts_utils.js b/src/utils/fonts_utils.js
index 2a1f0ea72..c3ff578bb 100644
--- a/src/utils/fonts_utils.js
+++ b/src/utils/fonts_utils.js
@@ -122,9 +122,9 @@ function readFontDictData(aString, aMap) {
       token = '';
       var parsed = false;
       while (!parsed) {
-        var byte = aString[i++];
+        var octet = aString[i++];
 
-        var nibbles = [parseInt(byte / 16, 10), parseInt(byte % 16, 10)];
+        var nibbles = [parseInt(octet / 16, 10), parseInt(octet % 16, 10)];
         for (var j = 0; j < nibbles.length; j++) {
           var nibble = nibbles[j];
           switch (nibble) {
@@ -175,7 +175,7 @@ function readFontDictData(aString, aMap) {
  * In CFF an INDEX is a structure with the following format:
  *  {
  *    count: 2 bytes (Number of objects stored in INDEX),
- *    offsize: 1 byte (Offset array element size),
+ *    offsize: 1 octet (Offset array element size),
  *    offset: [count + 1] bytes (Offsets array),
  *    data: - (Objects data)
  *  }
@@ -336,7 +336,7 @@ var Type2Parser = function type2Parser(aFilePath) {
     var privateDict = [];
     for (var i = 0; i < priv.size; i++)
       privateDict.push(aStream.getByte());
-    dump('private:' + privateDict);
+    dump('privateData:' + privateDict);
     parseAsToken(privateDict, CFFDictPrivateDataMap);
 
     for (var p in font.map)

From 9abbce021faf09a0d3f6c8631e4d9150704d320a Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Fri, 30 Mar 2012 23:28:11 +0200
Subject: [PATCH 16/18] Undo comment changes.

---
 src/fonts.js             | 54 ++++++++++++++++++++--------------------
 src/image.js             |  4 +--
 src/obj.js               |  4 +--
 src/parser.js            |  4 +--
 src/stream.js            |  6 ++---
 src/utils/fonts_utils.js |  2 +-
 6 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/src/fonts.js b/src/fonts.js
index 66c3be0f6..96452ab08 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -390,7 +390,7 @@ var symbolsFonts = {
   'Dingbats': true, 'Symbol': true, 'ZapfDingbats': true
 };
 
-// Some characters, e.g. copyrightserif, mapped to the privateData use area and
+// Some characters, e.g. copyrightserif, mapped to the private use area and
 // might not be displayed using standard fonts. Mapping/hacking well-known chars
 // to the similar equivalents in the normal characters range.
 function mapPrivateUseChars(code) {
@@ -1216,7 +1216,7 @@ var Font = (function FontClosure() {
       'Unknown'            // 9.Designer
     ];
 
-    // Mac want 1-octet per character strings while Windows want
+    // Mac want 1-byte per character strings while Windows want
     // 2-bytes per character, so duplicate the names table
     var stringsUnicode = [];
     for (var i = 0, ii = strings.length; i < ii; i++) {
@@ -1970,7 +1970,7 @@ var Font = (function FontClosure() {
             minUnicode = Math.min(minUnicode, unicode);
             maxUnicode = Math.max(maxUnicode, unicode);
           }
-          // high octet must be the same for min and max unicodes
+          // high byte must be the same for min and max unicodes
           if ((maxUnicode & 0xFF00) != (minUnicode & 0xFF00))
             this.isSymbolicFont = false;
         }
@@ -1986,7 +1986,7 @@ var Font = (function FontClosure() {
         if (hasShortCmap && this.hasEncoding && !this.isSymbolicFont) {
           // Re-encode short map encoding to unicode -- that simplifies the
           // resolution of MacRoman encoded glyphs logic for TrueType fonts:
-          // copying all characters to privateData use area, all mapping all known
+          // copying all characters to private use area, all mapping all known
           // glyphs to the unicodes. The glyphs and ids arrays will grow.
           var usedUnicodes = [];
           for (var i = 0, ii = glyphs.length; i < ii; i++) {
@@ -2114,7 +2114,7 @@ var Font = (function FontClosure() {
         var tableData = table.data;
         ttf.file += arrayToString(tableData);
 
-        // 4-octet aligned data
+        // 4-byte aligned data
         while (ttf.file.length & 3)
           ttf.file += String.fromCharCode(0);
       }
@@ -2504,12 +2504,12 @@ var Font = (function FontClosure() {
       glyphs = [];
 
       if (this.composite) {
-        // composite fonts have multi-octet strings convert the string from
-        // single-octet to multi-octet
-        // XXX assuming CIDFonts are two-octet - later need to extract the
-        // correct octet encoding according to the PDF spec
+        // composite fonts have multi-byte strings convert the string from
+        // single-byte to multi-byte
+        // XXX assuming CIDFonts are two-byte - later need to extract the
+        // correct byte encoding according to the PDF spec
         var length = chars.length - 1; // looping over two bytes at a time so
-                                       // loop should never end on the last octet
+                                       // loop should never end on the last byte
         for (var i = 0; i < length; i++) {
           var charcode = int16([chars.charCodeAt(i++), chars.charCodeAt(i)]);
           var glyph = this.charToGlyph(charcode);
@@ -2568,37 +2568,37 @@ var Type1Parser = function type1Parser() {
   /*
    * CharStrings are encoded following the the CharString Encoding sequence
    * describe in Chapter 6 of the "Adobe Type1 Font Format" specification.
-   * The value in a octet indicates a command, a number, or subsequent bytes
+   * The value in a byte indicates a command, a number, or subsequent bytes
    * that are to be interpreted in a special way.
    *
    * CharString Number Encoding:
-   *  A CharString octet containing the values from 32 through 255 inclusive
+   *  A CharString byte containing the values from 32 through 255 inclusive
    *  indicate an integer. These values are decoded in four ranges.
    *
-   * 1. A CharString octet containing a value, v, between 32 and 246 inclusive,
+   * 1. A CharString byte containing a value, v, between 32 and 246 inclusive,
    * indicate the integer v - 139. Thus, the integer values from -107 through
-   * 107 inclusive may be encoded in single octet.
+   * 107 inclusive may be encoded in single byte.
    *
-   * 2. A CharString octet containing a value, v, between 247 and 250 inclusive,
-   * indicates an integer involving the next octet, w, according to the formula:
+   * 2. A CharString byte containing a value, v, between 247 and 250 inclusive,
+   * indicates an integer involving the next byte, w, according to the formula:
    * [(v - 247) x 256] + w + 108
    *
-   * 3. A CharString octet containing a value, v, between 251 and 254 inclusive,
-   * indicates an integer involving the next octet, w, according to the formula:
+   * 3. A CharString byte containing a value, v, between 251 and 254 inclusive,
+   * indicates an integer involving the next byte, w, according to the formula:
    * -[(v - 251) * 256] - w - 108
    *
    * 4. A CharString containing the value 255 indicates that the next 4 bytes
    * are a two complement signed integer. The first of these bytes contains the
-   * highest order bits, the second octet contains the next higher order bits
-   * and the fourth octet contain the lowest order bits.
+   * highest order bits, the second byte contains the next higher order bits
+   * and the fourth byte contain the lowest order bits.
    *
    *
    * CharString Command Encoding:
    *  CharStrings commands are encoded in 1 or 2 bytes.
    *
-   *  Single octet commands are encoded in 1 octet that contains a value between
+   *  Single byte commands are encoded in 1 byte that contains a value between
    *  0 and 31 inclusive.
-   *  If a command octet contains the value 12, then the value in the next octet
+   *  If a command byte contains the value 12, then the value in the next byte
    *  indicates a command. This "escape" mechanism allows many extra commands
    * to be encoded and this encoding technique helps to minimize the length of
    * the charStrings.
@@ -3148,13 +3148,13 @@ Type1Font.prototype = {
     var count = objects.length;
 
     // If there is no object, just create an array saying that with another
-    // offset octet.
+    // offset byte.
     if (count == 0)
       return '\x00\x00\x00';
 
     var data = String.fromCharCode((count >> 8) & 0xFF, count & 0xff);
 
-    // Next octet contains the offset size use to reference object in the file
+    // 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
     // without thinking of it while coding.
     data += '\x04';
@@ -3800,7 +3800,7 @@ var CFFParser = (function CFFParserClosure() {
       return charStrings;
     },
     parsePrivateDict: function parsePrivateDict(parentDict) {
-      // no privateData dict, do nothing
+      // no private dict, do nothing
       if (!parentDict.hasName('Private'))
         return;
       var privateOffset = parentDict.getByName('Private');
@@ -3824,7 +3824,7 @@ var CFFParser = (function CFFParserClosure() {
                                         parentDict.strings);
       parentDict.privateDict = privateDict;
 
-      // Parse the Subrs index also since it's relative to the privateData dict.
+      // Parse the Subrs index also since it's relative to the private dict.
       if (!privateDict.getByName('Subrs'))
         return;
       var subrsOffset = privateDict.getByName('Subrs');
@@ -4611,7 +4611,7 @@ var CFFCompiler = (function CFFCompilerClosure() {
       else
         offsetSize = 4;
 
-      // Next octet contains the offset size use to reference object in the file
+      // Next byte contains the offset size use to reference object in the file
       data.push(offsetSize);
 
       // Add another offset after this one because we need a new offset
diff --git a/src/image.js b/src/image.js
index 22e79ba21..7c23a3426 100644
--- a/src/image.js
+++ b/src/image.js
@@ -314,7 +314,7 @@ var PDFImage = (function PDFImageClosure() {
       var originalHeight = this.height;
       var bpc = this.bpc;
 
-      // rows start at octet boundary;
+      // rows start at byte boundary;
       var rowBytes = (originalWidth * numComps * bpc + 7) >> 3;
       var imgArray = this.getImageBytes(originalHeight * rowBytes);
 
@@ -344,7 +344,7 @@ var PDFImage = (function PDFImageClosure() {
       var height = this.height;
       var bpc = this.bpc;
 
-      // rows start at octet boundary;
+      // rows start at byte boundary;
       var rowBytes = (width * numComps * bpc + 7) >> 3;
       var imgArray = this.getImageBytes(height * rowBytes);
 
diff --git a/src/obj.js b/src/obj.js
index cadc59127..2eb9c6f1d 100644
--- a/src/obj.js
+++ b/src/obj.js
@@ -438,7 +438,7 @@ var XRef = (function XRefClosure() {
       function skipUntil(data, offset, what) {
         var length = what.length, dataLength = data.length;
         var skipped = 0;
-        // finding octet sequence
+        // finding byte sequence
         while (offset < dataLength) {
           var i = 0;
           while (i < length && data[offset + i] == what[i])
@@ -494,7 +494,7 @@ var XRef = (function XRefClosure() {
           var content = buffer.subarray(position, position + contentLength);
 
           // checking XRef stream suspect
-          // (it shall have '/XRef' and next character is not a letter)
+          // (it shall have '/XRef' and next char is not a letter)
           var xrefTagOffset = skipUntil(content, 0, xrefBytes);
           if (xrefTagOffset < contentLength &&
               content[xrefTagOffset + 5] < 64) {
diff --git a/src/parser.js b/src/parser.js
index e2fcb056d..fad8b2c03 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -27,7 +27,7 @@ var Parser = (function ParserClosure() {
       if (isCmd(this.buf2, 'ID')) {
         this.buf1 = this.buf2;
         this.buf2 = null;
-        // skip octet after ID
+        // skip byte after ID
         this.lexer.skip();
       } else {
         this.buf1 = this.buf2;
@@ -424,7 +424,7 @@ var Lexer = (function LexerClosure() {
             stream.skip();
             var x2 = toHexDigit(stream.getChar());
             if (x2 == -1)
-              error('Illegal digit in hex character in name: ' + x2);
+              error('Illegal digit in hex char in name: ' + x2);
             str += String.fromCharCode((x << 4) | x2);
           } else {
             str += '#';
diff --git a/src/stream.js b/src/stream.js
index 6911b7163..d31f3d50b 100644
--- a/src/stream.js
+++ b/src/stream.js
@@ -1162,10 +1162,10 @@ var RunLengthStream = (function RunLengthStreamClosure() {
   RunLengthStream.prototype = Object.create(DecodeStream.prototype);
 
   RunLengthStream.prototype.readBlock = function runLengthStreamReadBlock() {
-    // The repeatHeader has following format. The first octet defines type of run
+    // The repeatHeader has following format. The first byte defines type of run
     // and amount of bytes to repeat/copy: n = 0 through 127 - copy next n bytes
-    // (in addition to the second octet from the header), n = 129 through 255 -
-    // duplicate the second octet from the header (257 - n) times, n = 128 - end.
+    // (in addition to the second byte from the header), n = 129 through 255 -
+    // duplicate the second byte from the header (257 - n) times, n = 128 - end.
     var repeatHeader = this.str.getBytes(2);
     if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] == 128) {
       this.eof = true;
diff --git a/src/utils/fonts_utils.js b/src/utils/fonts_utils.js
index c3ff578bb..65c02fce2 100644
--- a/src/utils/fonts_utils.js
+++ b/src/utils/fonts_utils.js
@@ -175,7 +175,7 @@ function readFontDictData(aString, aMap) {
  * In CFF an INDEX is a structure with the following format:
  *  {
  *    count: 2 bytes (Number of objects stored in INDEX),
- *    offsize: 1 octet (Offset array element size),
+ *    offsize: 1 byte (Offset array element size),
  *    offset: [count + 1] bytes (Offsets array),
  *    data: - (Objects data)
  *  }

From 2283f0bac1adccf5fccd2a62659e6d968303481f Mon Sep 17 00:00:00 2001
From: gigaherz <gigaherz@gmail.com>
Date: Sat, 31 Mar 2012 01:23:53 +0200
Subject: [PATCH 17/18] Decode the filename when assigning to title.

---
 web/viewer.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/web/viewer.js b/web/viewer.js
index d133b09da..8977b53c0 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -311,7 +311,7 @@ var PDFView = {
   open: function pdfViewOpen(url, scale) {
     this.url = url;
 
-    document.title = getFileName(url) || url;
+    document.title = decodeURIComponent(getFileName(url)) || url;
 
     if (!PDFView.loadingBar) {
       PDFView.loadingBar = new ProgressBar('#loadingBar', {});

From 6d9e04541347358f93eee3219622d5150efff8ad Mon Sep 17 00:00:00 2001
From: Artur Adib <arturadib@gmail.com>
Date: Tue, 3 Apr 2012 18:19:03 -0400
Subject: [PATCH 18/18] driver.js: retry POST until successful

---
 test/driver.js | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/test/driver.js b/test/driver.js
index 5a3263bda..8814da00e 100644
--- a/test/driver.js
+++ b/test/driver.js
@@ -266,6 +266,9 @@ function sendTaskResult(snapshot, task, failure) {
   r.onreadystatechange = function sendTaskResultOnreadystatechange(e) {
     if (r.readyState == 4) {
       inFlightRequests--;
+      // Retry until successful
+      if (r.status !== 200)
+        sendTaskResult(snapshot, task, failure);
     }
   };
   document.getElementById('inFlightCount').innerHTML = inFlightRequests++;