From e07505ff8da4b307d20a1faebe787c246f0cd36f Mon Sep 17 00:00:00 2001
From: Brendan Dahl <brendan.dahl@gmail.com>
Date: Tue, 21 Feb 2012 09:52:09 -0800
Subject: [PATCH] Update stats to use the new pdfBug panel.

---
 src/core.js     | 28 +++++++++---------
 src/util.js     | 14 ++++-----
 web/debugger.js | 75 ++++++++++++++++++++++++++++++++++++++++++++++++-
 web/viewer.css  | 24 ++++++----------
 web/viewer.js   | 34 ++++++----------------
 5 files changed, 112 insertions(+), 63 deletions(-)

diff --git a/src/core.js b/src/core.js
index f09ed927c..c816e7284 100644
--- a/src/core.js
+++ b/src/core.js
@@ -63,8 +63,8 @@ var Page = (function PageClosure() {
   function Page(xref, pageNumber, pageDict, ref) {
     this.pageNumber = pageNumber;
     this.pageDict = pageDict;
-    this.bench = new Bench();
-    this.bench.enabled = !!globalScope.PDFJS.enableBench;
+    this.stats = new StatTimer();
+    this.stats.enabled = !!globalScope.PDFJS.enableStats;
     this.xref = xref;
     this.ref = ref;
 
@@ -195,7 +195,7 @@ var Page = (function PageClosure() {
         return this.IRQueue;
       }
 
-      this.bench.time('Build IR Queue');
+      this.stats.time('Build IR Queue');
 
       var xref = this.xref;
       var content = xref.fetchIfRef(this.content);
@@ -216,12 +216,12 @@ var Page = (function PageClosure() {
       var IRQueue = {};
       this.IRQueue = pe.getIRQueue(content, resources, IRQueue, dependency);
 
-      this.bench.timeEnd('Build IR Queue');
+      this.stats.timeEnd('Build IR Queue');
       return this.IRQueue;
     },
 
     ensureFonts: function pageEnsureFonts(fonts, callback) {
-      this.bench.time('Font Loading');
+      this.stats.time('Font Loading');
       // Convert the font names to the corresponding font obj.
       for (var i = 0, ii = fonts.length; i < ii; i++) {
         fonts[i] = this.objs.objs[fonts[i]].data;
@@ -231,7 +231,7 @@ var Page = (function PageClosure() {
       var fontObjs = FontLoader.bind(
         fonts,
         function pageEnsureFontsFontObjs(fontObjs) {
-          this.bench.timeEnd('Font Loading');
+          this.stats.timeEnd('Font Loading');
 
           callback.call(this);
         }.bind(this),
@@ -240,8 +240,8 @@ var Page = (function PageClosure() {
     },
 
     display: function pageDisplay(gfx, callback) {
-      var bench = this.bench;
-      bench.time('Rendering');
+      var stats = this.stats;
+      stats.time('Rendering');
       var xref = this.xref;
       var resources = xref.fetchIfRef(this.resources);
       var mediaBox = xref.fetchIfRef(this.mediaBox);
@@ -269,8 +269,8 @@ var Page = (function PageClosure() {
         startIdx = gfx.executeIRQueue(IRQueue, startIdx, next, stepper);
         if (startIdx == length) {
           gfx.endDrawing();
-          bench.timeEnd('Rendering');
-          bench.timeEnd('Overall');
+          stats.timeEnd('Rendering');
+          stats.timeEnd('Overall');
           if (callback) callback();
         }
       }
@@ -413,8 +413,8 @@ var Page = (function PageClosure() {
       return items;
     },
     startRendering: function pageStartRendering(ctx, callback, textLayer)  {
-      var bench = this.bench;
-      bench.time('Overall');
+      var stats = this.stats;
+      stats.time('Overall');
       // If there is no displayReadyPromise yet, then the IRQueue was never
       // requested before. Make the request and create the promise.
       if (!this.displayReadyPromise) {
@@ -712,7 +712,7 @@ var PDFDoc = (function PDFDocClosure() {
         var pageNum = data.pageNum;
         var page = this.pageCache[pageNum];
         var depFonts = data.depFonts;
-        page.bench.timeEnd('Page Request');
+        page.stats.timeEnd('Page Request');
         page.startRenderingFromIRQueue(data.IRQueue, depFonts);
       }, this);
 
@@ -821,7 +821,7 @@ var PDFDoc = (function PDFDocClosure() {
     startRendering: function pdfDocStartRendering(page) {
       // The worker might not be ready to receive the page request yet.
       this.workerReadyPromise.then(function pdfDocStartRenderingThen() {
-        page.bench.time('Page Request');
+        page.stats.time('Page Request');
         this.messageHandler.send('page_request', page.pageNumber + 1);
       }.bind(this));
     },
diff --git a/src/util.js b/src/util.js
index 17ef81983..b6869b30f 100644
--- a/src/util.js
+++ b/src/util.js
@@ -416,26 +416,26 @@ var Promise = (function PromiseClosure() {
   return Promise;
 })();
 
-var Bench = (function BenchClosure() {
+var StatTimer = (function StatTimerClosure() {
   function rpad(str, pad, length) {
     while (str.length < length)
       str += pad;
     return str;
   }
-  function Bench() {
+  function StatTimer() {
     this.started = {};
     this.times = [];
     this.enabled = true;
   }
-  Bench.prototype = {
-    time: function benchTime(name) {
+  StatTimer.prototype = {
+    time: function statTimerTime(name) {
       if (!this.enabled)
         return;
       if (name in this.started)
         throw 'Timer is already running for ' + name;
       this.started[name] = Date.now();
     },
-    timeEnd: function benchTimeEnd(name) {
+    timeEnd: function statTimerTimeEnd(name) {
       if (!this.enabled)
         return;
       if (!(name in this.started))
@@ -448,7 +448,7 @@ var Bench = (function BenchClosure() {
       // Remove timer from started so it can be called again.
       delete this.started[name];
     },
-    toString: function benchToString() {
+    toString: function statTimerToString() {
       var times = this.times;
       var out = '';
       // Find the longest name for padding purposes.
@@ -466,5 +466,5 @@ var Bench = (function BenchClosure() {
       return out;
     }
   };
-  return Bench;
+  return StatTimer;
 })();
diff --git a/web/debugger.js b/web/debugger.js
index c759a5ee8..53fd332ea 100644
--- a/web/debugger.js
+++ b/web/debugger.js
@@ -312,6 +312,58 @@ var Stepper = (function StepperClosure() {
   return Stepper;
 })();
 
+var Stats = (function Stats() {
+  var stats = [];
+  function clear(node) {
+    while (node.hasChildNodes())
+      node.removeChild(node.lastChild);
+  }
+  function getStatIndex(pageNumber) {
+    for (var i = 0, ii = stats.length; i < ii; ++i)
+      if (stats[i].pageNumber === pageNumber)
+        return i;
+    return false;
+  }
+  return {
+    // Poperties/functions needed by PDFBug.
+    id: 'Stats',
+    name: 'Stats',
+    panel: null,
+    manager: null,
+    init: function init() {
+      this.panel.setAttribute('style', 'padding: 5px;');
+      PDFJS.enableStats = true;
+    },
+    enabled: false,
+    active: false,
+    // Stats specific functions.
+    add: function(pageNumber, stat) {
+      if (!stat)
+        return;
+      var statsIndex = getStatIndex(pageNumber);
+      if (statsIndex !== false) {
+        var b = stats[statsIndex];
+        this.panel.removeChild(b.div);
+        stats.splice(statsIndex, 1);
+      }
+      var wrapper = document.createElement('div');
+      wrapper.className = 'stats';
+      var title = document.createElement('div');
+      title.className = 'title';
+      title.textContent = 'Page: ' + pageNumber;
+      var statsDiv = document.createElement('div');
+      statsDiv.textContent = stat.toString();
+      wrapper.appendChild(title);
+      wrapper.appendChild(statsDiv);
+      stats.push({ pageNumber: pageNumber, div: wrapper });
+      stats.sort(function(a, b) { return a.pageNumber - b.pageNumber});
+      clear(this.panel);
+      for (var i = 0, ii = stats.length; i < ii; ++i)
+        this.panel.appendChild(stats[i].div);
+    }
+  };
+})();
+
 // Manages all the debugging tools.
 var PDFBug = (function PDFBugClosure() {
   var panelWidth = 300;
@@ -321,8 +373,29 @@ var PDFBug = (function PDFBugClosure() {
   return {
     tools: [
       FontInspector,
-      StepperManager
+      StepperManager,
+      Stats
     ],
+    enable: function(ids) {
+      var all = false, tools = this.tools;
+      if (ids.length === 1 && ids[0] === 'all')
+        all = true;
+      for (var i = 0; i < tools.length; ++i) {
+        var tool = tools[i];
+        if (all || ids.indexOf(tool.id) !== -1)
+          tool.enabled = true;
+      }
+      if (!all) {
+        // Sort the tools by the order they are enabled.
+        tools.sort(function(a, b) {
+          var indexA = ids.indexOf(a.id);
+          indexA = indexA < 0 ? tools.length : indexA;
+          var indexB = ids.indexOf(b.id);
+          indexB = indexB < 0 ? tools.length : indexB;
+          return indexA - indexB;
+        });
+      }
+    },
     init: function init() {
       /*
        * Basic Layout:
diff --git a/web/viewer.css b/web/viewer.css
index dc091daff..fdce0288a 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -65,22 +65,6 @@ body {
   line-height: 16px;
 }
 
-span#info {
-  display: none;
-  position: fixed;
-  top: 32px;
-  right: 0px;
-  font-size: 10px;
-  white-space: pre;
-  font-family: courier;
-}
-
-@-moz-document regexp("http:.*debug=1.*") {
-  span#info {
-    display: inline-block;
-  }
-}
-
 /* === Sidebar === */
 #sidebar {
   position: fixed;
@@ -448,3 +432,11 @@ canvas {
   background: yellow;
   opacity: 0.3;
 }
+#PDFBug .stats {
+  font-size: 10px;
+  white-space: pre;
+  font-family: courier;
+}
+#PDFBug .stats .title {
+  font-weight: bold;
+}
diff --git a/web/viewer.js b/web/viewer.js
index 816f14ffe..d66a8b5fd 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -458,7 +458,7 @@ var PDFView = {
     for (var i = 1; i <= pagesCount; i++) {
       var page = pdf.getPage(i);
       var pageView = new PageView(container, page, i, page.width, page.height,
-                                  page.bench, this.navigateTo.bind(this));
+                                  page.stats, this.navigateTo.bind(this));
       var thumbnailView = new ThumbnailView(sidebar, page, i,
                                             page.width / page.height);
       bindOnAfterDraw(pageView, thumbnailView);
@@ -635,7 +635,7 @@ var PDFView = {
 };
 
 var PageView = function pageView(container, content, id, pageWidth, pageHeight,
-                                 bench, navigateTo) {
+                                 stats, navigateTo) {
   this.id = id;
   this.content = content;
 
@@ -880,7 +880,7 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
       if (error)
         PDFView.error('An error occurred while rendering the page.', error);
 
-      self.stats = content.bench;
+      self.stats = content.stats;
       self.updateStats();
       if (self.onAfterDraw)
         self.onAfterDraw();
@@ -894,12 +894,10 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
   };
 
   this.updateStats = function pageViewUpdateStats() {
-    if (!PDFJS.enableBench || !this.stats || PDFView.page != this.id)
-      return;
-    var stats = this.stats;
-    var statsText = 'Page ' + this.id + '\n';
-    statsText += stats.toString();
-    document.getElementById('info').textContent = statsText;
+    if (PDFJS.pdfBug && Stats.enabled) {
+      var stats = this.stats;
+      Stats.add(this.id, stats);
+    }
   };
 };
 
@@ -1134,25 +1132,11 @@ window.addEventListener('load', function webViewerLoad(evt) {
   if ('pdfBug' in hashParams) {
     PDFJS.pdfBug = true;
     var pdfBug = hashParams['pdfBug'];
-    var all = false, enabled = [];
-    if (pdfBug === 'all')
-      all = true;
-    else
-      enabled = pdfBug.split(',');
-    var debugTools = PDFBug.tools;
-    for (var i = 0; i < debugTools.length; ++i) {
-      var tool = debugTools[i];
-      if (all || enabled.indexOf(tool.id) !== -1)
-        tool.enabled = true;
-    }
+    var enabled = pdfBug.split(',');
+    PDFBug.enable(enabled);
     PDFBug.init();
   }
 
-  if ('enableBench' in params)
-    PDFJS.enableBench = (params['enableBench'] === 'true');
-  if (PDFJS.enableBench)
-    document.getElementById('info').style.display = 'block';
-
   var sidebarScrollView = document.getElementById('sidebarScrollView');
   sidebarScrollView.addEventListener('scroll', updateThumbViewArea, true);
 }, true);