From 06cef910fb033e5abc208f65d4f4534db6191f6e Mon Sep 17 00:00:00 2001
From: Julian Viereck <julian.viereck@gmail.com>
Date: Thu, 15 Sep 2011 23:27:22 -0700
Subject: [PATCH] Cleanup Moz support in FontLoader

---
 fonts.js  | 197 ++++++++++++++++--------------------------------------
 worker.js |   7 +-
 2 files changed, 59 insertions(+), 145 deletions(-)

diff --git a/fonts.js b/fonts.js
index ff176c264..0de8fd379 100755
--- a/fonts.js
+++ b/fonts.js
@@ -290,152 +290,69 @@ var FontLoader = {
     return rule;
   },
 
-  bind: function(fonts, callback) {
+  bind: function(fontObj) {
     // If this isn't Gecko, we assume it's WebKit. See notes in bindWebKit.
     if (!isGecko) {
-      var fontObj = fonts[0];
       this.bindWebKit(fontObj.loadedName, fontObj);
-      return;
+    } else {
+      var rule = this.bindDOM(fontObj);
+      FontLoader.prepareFontLoadEvent(fontObj, rule);      
     }
-    
-     function checkFontsLoaded() {
-       for (var i = 0; i < objs.length; i++) {
-         var fontObj = objs[i];
-         if (fontObj.loading) {
-           return false;
-         }
-       }
+  },
 
-       document.documentElement.removeEventListener(
-         'pdfjsFontLoad', checkFontsLoaded, false);
+  // Set things up so that at least one pdfjsFontLoad event is
+  // dispatched when all the @font-face |rules| for |names| have been
+  // loaded in a subdocument.  It's expected that the load of |rules|
+  // has already started in this (outer) document, so that they should
+  // be ordered before the load in the subdocument.
+  prepareFontLoadEvent: function(fontObj, rule) {
+      /** Hack begin */
+      // There's no event when a font has finished downloading so the
+      // following code is a dirty hack to 'guess' when a font is
+      // ready.  This code will be obsoleted by Mozilla bug 471915.
+      //
+      // The only reliable way to know if a font is loaded in Gecko
+      // (at the moment) is document.onload in a document with
+      // a @font-face rule defined in a "static" stylesheet.  We use a
+      // subdocument in an <iframe>, set up properly, to know when
+      // our @font-face rule was loaded.  However, the subdocument and
+      // outer document can't share CSS rules, so the inner document
+      // is only part of the puzzle.  The second piece is an invisible
+      // div created in order to force loading of the @font-face in
+      // the *outer* document.  (The font still needs to be loaded for
+      // its metrics, for reflow).  We create the div first for the
+      // outer document, then create the iframe.  Unless something
+      // goes really wonkily, we expect the @font-face for the outer
+      // document to be processed before the inner.  That's still
+      // fragile, but seems to work in practice.
+      //
+      // The postMessage() hackery was added to work around chrome bug
+      // 82402.
 
-       callback();
-       return true;
-     }
-
-     var rules = [], names = [], objs = [];
-
-     for (var i = 0; i < fonts.length; i++) {
-       var font = fonts[i];
-       var obj = font;
-
-       objs.push(obj);
-
-       var str = '';
-       var rule = this.bindDOM(font);
-       if (rule) {
-         rules.push(rule);
-         names.push(obj.loadedName);
-       }
-     }
-
-     // console.log("bind", fonts, rules, names);
-
-     this.listeningForFontLoad = false;
-     if (!isWorker && rules.length) {
-       FontLoader.prepareFontLoadEvent(rules, names, objs);
-     }
-
-     if (!checkFontsLoaded()) {
-       document.documentElement.addEventListener(
-         'pdfjsFontLoad', checkFontsLoaded, false);
-     }
-
-     return objs;
-   },
-   // Set things up so that at least one pdfjsFontLoad event is
-   // dispatched when all the @font-face |rules| for |names| have been
-   // loaded in a subdocument.  It's expected that the load of |rules|
-   // has already started in this (outer) document, so that they should
-   // be ordered before the load in the subdocument.
-   prepareFontLoadEvent: function(rules, names, objs) {
-       /** Hack begin */
-       // There's no event when a font has finished downloading so the
-       // following code is a dirty hack to 'guess' when a font is
-       // ready.  This code will be obsoleted by Mozilla bug 471915.
-       //
-       // The only reliable way to know if a font is loaded in Gecko
-       // (at the moment) is document.onload in a document with
-       // a @font-face rule defined in a "static" stylesheet.  We use a
-       // subdocument in an <iframe>, set up properly, to know when
-       // our @font-face rule was loaded.  However, the subdocument and
-       // outer document can't share CSS rules, so the inner document
-       // is only part of the puzzle.  The second piece is an invisible
-       // div created in order to force loading of the @font-face in
-       // the *outer* document.  (The font still needs to be loaded for
-       // its metrics, for reflow).  We create the div first for the
-       // outer document, then create the iframe.  Unless something
-       // goes really wonkily, we expect the @font-face for the outer
-       // document to be processed before the inner.  That's still
-       // fragile, but seems to work in practice.
-       //
-       // The postMessage() hackery was added to work around chrome bug
-       // 82402.
-
-       var div = document.createElement('div');
-       div.setAttribute('style',
-                        'visibility: hidden;' +
-                        'width: 10px; height: 10px;' +
-                        'position: absolute; top: 0px; left: 0px;');
-       var html = '';
-       for (var i = 0; i < names.length; ++i) {
-         html += '<span style="font-family:' + names[i] + '">Hi</span>';
-       }
-       div.innerHTML = html;
-       document.body.appendChild(div);
-
-       if (!this.listeningForFontLoad) {
-         window.addEventListener(
-           'message',
-           function(e) {
-             var fontNames = JSON.parse(e.data);
-             for (var i = 0; i < objs.length; ++i) {
-               var font = objs[i];
-               font.loading = false;
-             }
-             var evt = document.createEvent('Events');
-             evt.initEvent('pdfjsFontLoad', true, false);
-             document.documentElement.dispatchEvent(evt);
-           },
-           false);
-         this.listeningForFontLoad = true;
-       }
-
-       // XXX we should have a time-out here too, and maybe fire
-       // pdfjsFontLoadFailed?
-       var src = '<!DOCTYPE HTML><html><head>';
-       src += '<style type="text/css">';
-       for (var i = 0; i < rules.length; ++i) {
-         src += rules[i];
-       }
-       src += '</style>';
-       src += '<script type="application/javascript">';
-       var fontNamesArray = '';
-       for (var i = 0; i < names.length; ++i) {
-         fontNamesArray += '"' + names[i] + '", ';
-       }
-       src += '  var fontNames=[' + fontNamesArray + '];\n';
-       src += '  window.onload = function () {\n';
-       // src += '    parent.postMessage(JSON.stringify(fontNames), "*");\n';
-       src += '  }';
-       src += '</script></head><body>';
-       for (var i = 0; i < names.length; ++i) {
-         src += '<p style="font-family:\'' + names[i] + '\'">Hi</p>';
-       }
-       src += '</body></html>';
-       var frame = document.createElement('iframe');
-       frame.src = 'data:text/html,' + src;
-       frame.setAttribute('style',
-                          'visibility: hidden;' +
-                          'width: 10px; height: 10px;' +
-                          'position: absolute; top: 0px; left: 0px;');
-       document.body.appendChild(frame);
-       frame.onload = function() {
-         Objects.resolve(names[0]);
-       }
-       /** Hack end */
-   }
- };
+      // XXX we should have a time-out here too, and maybe fire
+      // pdfjsFontLoadFailed?
+      var src = '<!DOCTYPE HTML><html><head>';
+      src += '<style type="text/css">';
+      src += rule;
+      src += '</style>';
+      src += '</script>';
+      src += '</head><body>';
+      src += '<p style="font-family:\'' + fontObj.loadedName + '\'">Hi</p>'
+      src += '</body></html>';
+      var frame = document.createElement('iframe');
+      frame.src = 'data:text/html,' + src;
+      frame.setAttribute('style',
+                         'visibility: hidden;' +
+                         'width: 10px; height: 10px;' +
+                         'position: absolute; top: 0px; left: 0px;');
+      document.body.appendChild(frame);
+      
+      frame.onload = function() {
+        Objects.resolve(fontObj.loadedName);
+      }
+      /** Hack end */
+  }
+};
 
 if (!isWorker) {
   FontLoader.setup();
diff --git a/worker.js b/worker.js
index 38b60ad8c..021114683 100644
--- a/worker.js
+++ b/worker.js
@@ -136,7 +136,7 @@ var Promise = (function() {
     
     resolve: function(data) {
       if (this.isResolved) {
-        throw "A Promise can be resolved only once";
+        throw "A Promise can be resolved only once " + this.name;
       }
       
       this.isResolved = true;
@@ -229,10 +229,7 @@ var WorkerPDFDoc = (function() {
         Objects.resolve(objId, fontObj);
       } else {
         Objects.setData(objId, fontObj);
-        FontLoader.bind([fontObj], function() {
-          console.log("loaded", fontObj.loadedName);
-          Objects.resolve(objId);
-        });
+        FontLoader.bind(fontObj);
       }
     });