From 7e5a9b7a394d88b210d0a12d74320a79b857cfd7 Mon Sep 17 00:00:00 2001
From: Brendan Dahl <brendan.dahl@gmail.com>
Date: Thu, 28 Jun 2012 09:50:25 -0700
Subject: [PATCH] Adds support for the new mozPrintCallback api.

---
 web/viewer.css  | 30 +++++++++++------------
 web/viewer.html |  1 +
 web/viewer.js   | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+), 16 deletions(-)

diff --git a/web/viewer.css b/web/viewer.css
index b8e86f2c8..b57af0591 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -1113,28 +1113,26 @@ canvas {
   font-size: 10px;
 }
 
-@media print {
-  #sidebarContainer, .toolbar, #loadingBox, #errorWrapper, .textLayer {
-    display: none;
-  }
+@page {
+  margin: 0;
+} 
 
-  #mainContainer, #viewerContainer, .page, .page canvas {
-    position: static;
-    padding: 0;
-    margin: 0;
-  }
+#printContainer {
+  display: none;
+}
 
-  .page {
-    float: left;
+@media print {
+  #outerContainer {
     display: none;
-    -webkit-box-shadow: none;
-    -moz-box-shadow: none;
-    box-shadow: none;
   }
-
-  .page[data-loaded] {
+  #printContainer {
     display: block;
   }
+  canvas {
+    position: relative;
+    top: 0;
+    left: 0;
+  }
 }
 
 @media all and (max-width: 950px) {
diff --git a/web/viewer.html b/web/viewer.html
index c59d9fcf3..5d66e8b33 100644
--- a/web/viewer.html
+++ b/web/viewer.html
@@ -176,5 +176,6 @@
       </div> <!-- mainContainer -->
 
     </div> <!-- outerContainer -->
+    <div id="printContainer"></div>
   </body>
 </html>
diff --git a/web/viewer.js b/web/viewer.js
index 516081f6f..1a7732e4e 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -379,6 +379,11 @@ var PDFView = {
     return currentPageNumber;
   },
 
+  get supportsPrinting() {
+    var canvas = document.createElement('canvas');
+    return 'mozPrintCallback' in canvas;
+  },
+
   open: function pdfViewOpen(url, scale, password) {
     var parameters = {password: password};
     if (typeof url === 'string') { // URL
@@ -1041,6 +1046,22 @@ var PDFView = {
       params[unescape(key)] = unescape(value);
     }
     return params;
+  },
+
+  beforePrint: function pdfViewSetupBeforePrint() {
+    if (!this.supportsPrinting) {
+      alert('Printing is not supported by this browser.');
+      return;
+    }
+    for (var i = 0, ii = this.pages.length; i < ii; ++i) {
+      this.pages[i].beforePrint();
+    }
+  },
+
+  afterPrint: function pdfViewSetupAfterPrint() {
+    var div = document.getElementById('printContainer');
+    while (div.hasChildNodes())
+      div.removeChild(div.lastChild);
   }
 };
 
@@ -1360,6 +1381,40 @@ var PageView = function pageView(container, pdfPage, id, scale,
     div.setAttribute('data-loaded', true);
   };
 
+  this.beforePrint = function pageViewBeforePrint() {
+    var pdfPage = this.pdfPage;
+    var viewport = pdfPage.getViewport(1);
+
+    var canvas = this.canvas = document.createElement('canvas');
+    canvas.width = viewport.width;
+    canvas.height = viewport.height;
+    canvas.style.width = viewport.width + 'pt';
+    canvas.style.height = viewport.height + 'pt';
+
+    var printContainer = document.getElementById('printContainer');
+    printContainer.appendChild(canvas);
+
+    var self = this;
+    canvas.mozPrintCallback = function(obj) {
+      var ctx = obj.context;
+      var renderContext = {
+        canvasContext: ctx,
+        viewport: viewport
+      };
+
+      pdfPage.render(renderContext).then(function() {
+        // Tell the printEngine that rendering this canvas/page has finished.
+        obj.done();
+        self.pdfPage.destroy();
+      }, function(error) {
+        console.error(error);
+        // Tell the printEngine that rendering this canvas/page has failed.
+        // This will make the print proces stop.
+        obj.abort();
+      });
+    };
+  };
+
   this.updateStats = function pageViewUpdateStats() {
     if (PDFJS.pdfBug && Stats.enabled) {
       var stats = this.stats;
@@ -1960,3 +2015,11 @@ window.addEventListener('keydown', function keydown(evt) {
     evt.preventDefault();
   }
 });
+
+window.addEventListener('beforeprint', function beforePrint(evt) {
+  PDFView.beforePrint();
+});
+
+window.addEventListener('afterprint', function afterPrint(evt) {
+  PDFView.afterPrint();
+});