]> git.parisson.com Git - pdf.js.git/commitdiff
Add a root 'Font' class as the outside world API
authorVivien Nicolas <21@vingtetun.org>
Sun, 12 Jun 2011 23:38:05 +0000 (01:38 +0200)
committerVivien Nicolas <21@vingtetun.org>
Sun, 12 Jun 2011 23:38:05 +0000 (01:38 +0200)
PDFFont.js
pdf.js

index 84fdf94b140f66cc17a3ec9ca6cbfb7025b7ae66..15e5f2c32632501e86e4aca5763fd703af1b82b7 100644 (file)
@@ -1,19 +1,86 @@
 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 
-var kMaxFontFileSize = 100000;
+/**
+ * Hold a map of decoded fonts and of the standard fourteen Type1 fonts and
+ * their acronyms.
+ * TODO Add the standard fourteen Type1 fonts list by default
+ *      http://cgit.freedesktop.org/poppler/poppler/tree/poppler/GfxFont.cc#n65
+ */
+var Fonts = {};
+
 
 /**
- * This dictionary holds decoded fonts data.
+ * 'Font' is the class the outside world should use, it encapsulate all the font
+ * decoding logics whatever type it is (assuming the font type is supported).
+ *
+ * For example to read a Type1 font and to attach it to the document:
+ *   var type1Font = new Font("MyFontName", binaryData, "Type1");
+ *   type1Font.bind();
+ *
+ * As an improvment the last parameter can be replaced by an automatic guess
+ * of the font type based on the first byte of the file.
  */
-var Fonts = new Dict();
+var Font = function(aFontName, aFontFile, aFontType) {
+  this.name = aFontName;
+
+  // If the font has already been decoded simply return
+  if (Fonts[aFontName]) {
+    this.font = Fonts[aFontName];
+    return;
+  }
+
+  switch (aFontType) {
+    case "Type1":
+      this.mimetype = "font/otf";
+      this.font = new Type1(aFontName, aFontFile);
+      break;
+    case "TrueType":
+      this.mimetype = "font/ttf";
+      this.font = new TrueType(aFontName, aFontFile);
+      break;
+    default:
+      error("Font " + aFontType + " is not supported");
+      break;
+  }
+
+  Fonts[aFontName] = this.font;
+  this.bind();
+};
+
+Font.prototype = {
+  name: null,
+  font: null,
+  mimetype: null,
+
+  bind: function() {
+    var data = this.font.data;
+
+    // Compute the binary data to base 64
+    var str = [];
+    var count = data.length;
+    for (var i = 0; i < count; i++)
+      str.push(data.getChar ? data.getChar()
+                            : String.fromCharCode(data[i]));
+
+    var dataBase64 = window.btoa(str.join(""));
+
+    // Add the @font-face rule to the document
+    var url = "url(data:" + this.mimetype + ";base64," + dataBase64 + ");";
+    var rule = "@font-face { font-family:'" + this.name + "';src:" + url + "}";
+    var styleSheet = document.styleSheets[0];
+    styleSheet.insertRule(rule, styleSheet.length);
+  }
+};
+
+/** Implementation dirty logic starts here */
+
+var kMaxFontFileSize = 100000;
 
 /**
- * This simple object keep a trace of the fonts that have already been decoded
- * by storing a map between the name given by the PDF and the name gather from
- * the font (aka the PostScript code of the font itself for Type1 font).
+ * This dictionary holds decoded fonts data.
  */
-var _Fonts = {};
+var PSFonts = new Dict();
 
 
 var Stack = function() {
@@ -57,27 +124,7 @@ var Stack = function() {
   };
 };
 
-var Base64Encoder = {
-  encode: function(aFontName, aData) {
-    var str = [];
-    var count = aData.length;
-    for (var i = 0; i < count; i++)
-      str.push(aData.getChar ? aData.getChar() : String.fromCharCode(aData[i]));
-
-    // Add the css rule to the document
-    var fontData = window.btoa(str.join(""));
-    var url = "url(data:font/otf;base64," + fontData + ");";
-    document.styleSheets[0].insertRule("@font-face { font-family: '" + aFontName + "'; src: " + url + " }", 0);
-
-    return fontData;
-  }
-};
-
-var TrueTypeFont = function(aFontName, aFontFile) {
-  if (_Fonts[aFontName])
-    return;
-  _Fonts[aFontName] = true;
-
+var TrueType = function(aFontName, aFontFile) {
   var debug = true;
   function dump(aMsg) {
     if (debug)
@@ -85,8 +132,7 @@ var TrueTypeFont = function(aFontName, aFontFile) {
   }
 
   dump("Loading a TrueType font: " + aFontName);
-  var fontData = Base64Encoder.encode(aFontName, aFontFile);
-  Fonts.set(aFontName, fontData);
+  this.data = aFontFile;
 };
 
 var Type1Parser = function(aAsciiStream, aBinaryStream) {
@@ -485,14 +531,6 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
         case "def":
           var value = operandStack.pop();
           var key = operandStack.pop();
-
-          // XXX we don't want to do that here but for some reasons the names
-          // are different between what is declared and the FontName directive
-          if (key == "FontName" && Fonts.get(value)) {
-            // The font has already be decoded, stop!
-            return true;
-          }
-
           dump("def: " + key + " = " + value);
           dictionaryStack.peek().set(key, value);
           break;
@@ -504,7 +542,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
 
           // The key will be the identifier to recognize this font
           fontName = key;
-          Fonts.set(key, font);
+          PSFonts.set(key, font);
 
           operandStack.push(font);
           break;
@@ -722,11 +760,7 @@ var Type1Parser = function(aAsciiStream, aBinaryStream) {
 
 
 var fontCount = 0;
-var Type1Font = function(aFontName, aFontFile) {
-  if (_Fonts[aFontName])
-    return;
-  _Fonts[aFontName] = true;
-
+var Type1 = function(aFontName, aFontFile) {
   // All Type1 font program should begin with the comment %!
   if (aFontFile.getByte() != 0x25 || aFontFile.getByte() != 0x21)
     error("Invalid file header");
@@ -740,17 +774,14 @@ var Type1Font = function(aFontName, aFontFile) {
 
     this.parser = new Type1Parser(ASCIIStream, binaryStream);
     var fontName = this.parser.parse();
-    var font = Fonts.get(fontName);
-    var fontData = this.convertToOTF(this.convertToCFF(font), font);
-    fontData = Base64Encoder.encode(aFontName, fontData);
-    Fonts.set(aFontName, fontData);
-
+    var font = PSFonts.get(fontName);
+    this.data = this.convertToOTF(this.convertToCFF(font), font);
     var end = Date.now();
     log("Time to parse font is:" + (end - start));
   }
 };
 
-Type1Font.prototype = {
+Type1.prototype = {
   getDefaultWidth: function(aCharstrings) {
     var defaultWidth = 0;
     var defaultUsedCount = 0;
@@ -1104,11 +1135,6 @@ Type1Font.prototype = {
     value = 2;
     for (var i = 1; i < maxPower; i++)
       value *= 2;
-
-    if (fontCount == 5) {
-      log ("mp2: " + aNumber + "::" + value);
-    }
-
     return value;
   },
 
@@ -1480,7 +1506,7 @@ Type1Font.prototype = {
     for (var i = 0; i < currentOffset; i++)
       fontData.push(otf[i]);
 
-    writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf");
+    //writeToFile(fontData, "/tmp/pdf.js." + fontCount + ".otf");
     return fontData;
   }
 };
diff --git a/pdf.js b/pdf.js
index cdc035c28f5cd8d5250853c3d43e5a1def93cc66..06928ca093c2e4a884d66dd0a5d41686e12fc13d 100644 (file)
--- a/pdf.js
+++ b/pdf.js
@@ -2278,37 +2278,14 @@ var CanvasGraphics = (function() {
 
             var fontName = "";
             var subtype = font.get("Subtype").name;
-            switch (subtype) {
-              case "Type1":
-                var fontDescriptor = font.get("FontDescriptor");
-                if (fontDescriptor.num) {
-                  // XXX fetchIfRef looks expensive
-                  var fontDescriptor = this.xref.fetchIfRef(fontDescriptor);
-                  var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile"));
-                  fontName = fontDescriptor.get("FontName").name;
-                  fontName = fontName.replace("+", ""); // no + are allowed in the font name
-                  font = new Type1Font(fontName, fontFile);
-                }
-                break;
-
-              case "Type3":
-                TODO("support Type3 font");
-                break;
-
-              case "TrueType":
-                var fontDescriptor = font.get("FontDescriptor");
-                if (fontDescriptor.num) {
-                  var fontDescriptor = this.xref.fetchIfRef(fontDescriptor);
-                  var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile2"));
-                  fontName = fontDescriptor.get("FontName").name;
-                  fontName = fontName.replace("+", ""); // no + are allowed in the font name
-                  font = new TrueTypeFont(fontName, fontFile);
-                }
-                break;
-
-              default:
-                error("Unsupported font type: " + subtype);
-                break;
+            var fontDescriptor = font.get("FontDescriptor");
+            if (fontDescriptor.num) {
+                var fontDescriptor = this.xref.fetchIfRef(fontDescriptor);
+                var fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile"));
+                if (!fontFile)
+                  fontFile = this.xref.fetchIfRef(fontDescriptor.get("FontFile2"));
+                fontName = fontDescriptor.get("FontName").name.replace("+", " ");
+                new Font(fontName, fontFile, subtype);
             }
 
             this.current.fontSize = size;