]> git.parisson.com Git - pdf.js.git/commitdiff
merge
authorChris Jones <jones.chris.g@gmail.com>
Fri, 1 Jul 2011 08:23:20 +0000 (01:23 -0700)
committerChris Jones <jones.chris.g@gmail.com>
Fri, 1 Jul 2011 08:23:20 +0000 (01:23 -0700)
1  2 
fonts.js

diff --cc fonts.js
index 6aed3ee976ed065b5de1976519dca86451cfd1ed,9782fc9a1ceaeb791db79c0b408d9af008793a64..793ba99ef392c7a6b1b9083438922d8f213ebe0d
+++ b/fonts.js
@@@ -119,131 -124,30 +124,129 @@@ var Fonts = (function () 
  })();
  
  var FontLoader = {
 -  bind: function(fonts) {
 -    var ready = true;
 +  bind: function(fonts, callback) {
-     var worker = (typeof window == "undefined");
 +    function checkFontsLoaded() {
 +      for (var i = 0; i < fonts.length; i++) {
 +        var font = fonts[i];
 +        if (Fonts.lookup(font.name).loading) {
 +          return false;
 +        }
 +      }
 +
 +      document.documentElement.removeEventListener(
 +        "pdfjsFontLoad", checkFontsLoaded, false);
 +
 +      callback();
 +      return true;
 +    }
  
 +    var rules = [ ], names = [ ];
      for (var i = 0; i < fonts.length; i++) {
        var font = fonts[i];
 -      if (Fonts.lookup(font.name)) {
 -        ready = ready && !Fonts.lookup(font.name).loading;
 -        continue;
 +      if (!Fonts.lookup(font.name)) {
 +        var obj = new Font(font.name, font.file, font.properties);
 +
 +        var str = "";
 +        var data = Fonts.lookup(font.name).data;
 +        var length = data.length;
 +        for (var j = 0; j < length; j++)
 +          str += String.fromCharCode(data[j]);
 +
-         var rule = worker ? obj.bindWorker(str) : obj.bindDOM(str);
++        var rule = isWorker ? obj.bindWorker(str) : obj.bindDOM(str);
 +        if (rule) {
 +          rules.push(rule);
 +          names.push(font.name);
 +        }
        }
 +    }
  
-     if (!worker && rules.length) {
 -      ready = false;
++    if (!isWorker && rules.length) {
 +      FontLoader.prepareFontLoadEvent(rules, names);
 +    }
  
 -      var obj = new Font(font.name, font.file, font.properties);
 +    if (!checkFontsLoaded()) {
 +      document.documentElement.addEventListener(
 +        "pdfjsFontLoad", checkFontsLoaded, false);
 +    }
  
 -      var str = "";
 -      var data = Fonts.lookup(font.name).data;
 -      var length = data.length;
 -      for (var j = 0; j < length; j++)
 -        str += String.fromCharCode(data[j]);
 +    return;
 +  },
 +  // 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) {
 +      /** 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.
  
 -      isWorker ? obj.bindWorker(str) : obj.bindDOM(str);
 -    }
 +      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);
  
 -    return ready;
 +      // 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 += '    var Fonts = top.document.defaultView.Fonts;\n';
 +      src += '    for (var i = 0; i < fontNames.length; ++i) {\n';
 +      src += '      var font = Fonts.lookup(fontNames[i]);\n';
 +      src += '      font.loading = false;\n';
 +      src += '    }\n';
 +      src += '    var doc = top.document;\n';
 +      src += '    var evt = doc.createEvent("Events");\n';
 +      src += '    evt.initEvent("pdfjsFontLoad", true, false);\n'
 +      src += '    doc.documentElement.dispatchEvent(evt);\n';
 +      src += '  }';
 +      src += '</script></head><body>';
 +      for (var i = 0; i < names.length; ++i) {
 +        src += '<p style="font-family:\''+ fontName +'\'">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);
 +      /** Hack end */
    }
  };