]> git.parisson.com Git - pdf.js.git/commitdiff
CFF/OTF font and sanitizer friendly fixes
authornotmasteryet <async.processingjs@yahoo.com>
Sun, 10 Jul 2011 04:12:11 +0000 (23:12 -0500)
committernotmasteryet <async.processingjs@yahoo.com>
Sun, 10 Jul 2011 04:12:11 +0000 (23:12 -0500)
fonts.js

index f6620a0a064362e3ffe01322259e92e36999a00e..1d2a5f755a232862b0a525e0b0c94cd2df5c8722 100755 (executable)
--- a/fonts.js
+++ b/fonts.js
@@ -584,21 +584,12 @@ var Font = (function() {
                '\x00\x01' + // encodingID
                string32(4 + numTables * 8); // start of the table record
 
-    var headerSize = (12 * 2 + (ranges.length * 5 * 2));
     var segCount = ranges.length + 1;
     var segCount2 = segCount * 2;
     var searchRange = getMaxPower2(segCount) * 2;
     var searchEntry = Math.log(segCount) / Math.log(2);
     var rangeShift = 2 * segCount - searchRange;
 
-    var format314 = '\x00\x04' + // format
-                    string16(headerSize) + // length
-                    '\x00\x00' + // language
-                    string16(segCount2) +
-                    string16(searchRange) +
-                    string16(searchEntry) +
-                    string16(rangeShift);
-
     // Fill up the 4 parallel arrays describing the segments.
     var startCount = '';
     var endCount = '';
@@ -610,7 +601,7 @@ var Font = (function() {
       var range = ranges[i];
       var start = range[0];
       var end = range[1];
-      var delta = (bias - start) % 0xffff;
+      var delta = (bias - start) & 0xffff;
       bias += (end - start + 1);
 
       startCount += string16(start);
@@ -627,10 +618,19 @@ var Font = (function() {
     startCount += '\xFF\xFF';
     idDeltas += '\x00\x01';
     idRangeOffsets += '\x00\x00';
-    format314 += endCount + '\x00\x00' + startCount +
-                 idDeltas + idRangeOffsets + glyphsIds;
 
-    return stringToArray(cmap + format314);
+    var format314 = '\x00\x00' + // language
+                    string16(segCount2) +
+                    string16(searchRange) +
+                    string16(searchEntry) +
+                    string16(rangeShift) +
+                    endCount + '\x00\x00' + startCount +
+                    idDeltas + idRangeOffsets + glyphsIds;
+
+    return stringToArray(cmap +
+                         '\x00\x04' + // format
+                         string16(format314.length + 4) + // length
+                         format314);
   };
 
   function createOS2Table(properties) {
@@ -949,11 +949,6 @@ var Font = (function() {
 
     convert: function font_convert(fontName, font, properties) {
       function createNameTable(name) {
-        // All the strings of the name table should be an odd number
-        // of bytes
-        if (name.length % 2)
-          name = name.slice(0, name.length - 1);
-
         var strings = [
           'Original licence',  // 0.Copyright
           name,                // 1.Font family
@@ -961,7 +956,7 @@ var Font = (function() {
           'uniqueID',          // 3.Unique ID
           name,                // 4.Full font name
           'Version 0.11',      // 5.Version
-          'Unknown',           // 6.Postscript name
+          '',                  // 6.Postscript name
           'Unknown',           // 7.Trademark
           'Unknown',           // 8.Manufacturer
           'Unknown'            // 9.Designer
@@ -1000,7 +995,7 @@ var Font = (function() {
               platforms[i] + // platform ID
               encodings[i] + // encoding ID
               languages[i] + // language ID
-              string16(i) + // name ID
+              string16(j) + // name ID
               string16(str.length) +
               string16(strOffset);
             nameTable += nameRecord;
@@ -1390,6 +1385,18 @@ var Type1Parser = function() {
     return array;
   };
 
+  function readNumber(str, index) {
+    while (str[index++] == ' ')
+      ;
+    var start = index;
+
+    var count = 0;
+    while (str[index++] != ' ')
+      count++;
+
+    return parseFloat(str.substr(start, count) || 0);
+  };
+
   this.extractFontProgram = function t1_extractFontProgram(stream) {
     var eexec = decrypt(stream, kEexecEncryptionKey, 4);
     var eexecStr = '';
@@ -1401,8 +1408,7 @@ var Type1Parser = function() {
       subrs: [],
       charstrings: [],
       properties: {
-        stemSnapH: [0, 0],
-        stemSnapV: [0, 0]
+        private: {}
       }
     };
 
@@ -1444,17 +1450,24 @@ var Type1Parser = function() {
             case '/Subrs':
               subrsSection = true;
               break;
-            case '/StdHW':
-              program.properties.stdHW = readNumberArray(eexecStr, i + 2)[0];
+            case '/BlueValues':
+            case '/OtherBlues':
+            case '/FamilyBlues':
+            case '/FamilyOtherBlues':
+            case '/StemSnapH':
+            case '/StemSnapV':
+              program.properties.private[token.substring(1)] = readNumberArray(eexecStr, i + 2);
               break;
+            case '/StdHW':
             case '/StdVW':
-              program.properties.stdVW = readNumberArray(eexecStr, i + 2)[0];
+              program.properties.private[token.substring(1)] = readNumberArray(eexecStr, i + 2)[0];
               break;
-            case '/StemSnapH':
-              program.properties.stemSnapH = readNumberArray(eexecStr, i + 2);
-              break;
-            case '/StemSnapV':
-              program.properties.stemSnapV = readNumberArray(eexecStr, i + 2);
+            case '/BlueShift':
+            case '/BlueFuzz':
+            case '/BlueScale':
+            case '/LanguageGroup':
+            case '/ExpansionFactor':
+              program.properties.private[token.substring(1)] = readNumber(eexecStr, i + 1);
               break;
           }
         } else if (c == '/') {
@@ -1644,7 +1657,7 @@ CFF.prototype = {
       return '\x1c' +
              String.fromCharCode((value >> 8) & 0xFF) +
              String.fromCharCode(value & 0xFF);
-    } else if (value >= (-2147483647-1) && value <= 2147483647) {
+    } else if (value >= (-2147483648) && value <= 2147483647) {
       return '\xff' +
              String.fromCharCode((value >>> 24) & 0xFF) +
              String.fromCharCode((value >> 16) & 0xFF) +
@@ -1771,10 +1784,10 @@ CFF.prototype = {
           var dict =
               '\x00\x01\x01\x01\x30' +
               '\xf8\x1b\x00' + // version
-              '\xf8\x1b\x01' + // Notice
-              '\xf8\x1b\x02' + // FullName
-              '\xf8\x1b\x03' + // FamilyName
-              '\xf8\x1b\x04' +  // Weight
+              '\xf8\x1c\x01' + // Notice
+              '\xf8\x1d\x02' + // FullName
+              '\xf8\x1e\x03' + // FamilyName
+              '\xf8\x1f\x04' +  // Weight
               '\x1c\x00\x00\x10'; // Encoding
 
           var boundingBox = properties.bbox;
@@ -1793,7 +1806,7 @@ CFF.prototype = {
           dict += self.encodeNumber(offset) + '\x11'; // Charstrings
 
           dict += self.encodeNumber(fields.private.length);
-          var offset = offset + fields.charstrings.length;
+          offset = offset + fields.charstrings.length;
           dict += self.encodeNumber(offset) + '\x12'; // Private
 
           return dict;
@@ -1837,19 +1850,33 @@ CFF.prototype = {
       'private': (function(self) {
         var data =
             '\x8b\x14' + // defaultWidth
-            '\x8b\x15' + // nominalWidth
-            self.encodeNumber(properties.stdHW || 0) + '\x0a' + // StdHW
-            self.encodeNumber(properties.stdVW || 0) + '\x0b';  // StdVW
-
-        var stemH = properties.stemSnapH;
-        for (var i = 0; i < stemH.length; i++)
-          data += self.encodeNumber(stemH[i]);
-        data += '\x0c\x0c'; // StemSnapH
-
-        var stemV = properties.stemSnapV;
-        for (var i = 0; i < stemV.length; i++)
-          data += self.encodeNumber(stemV[i]);
-        data += '\x0c\x0d'; // StemSnapV
+            '\x8b\x15';  // nominalWidth
+        var fieldMap = {
+          BlueValues: '\x06',
+          OtherBlues: '\x07',
+          FamilyBlues: '\x08',
+          FamilyOtherBlues: '\x09',
+          StemSnapH: '\x0c\x0c',
+          StemSnapV: '\x0c\x0d',
+          BlueShift: '\x0c\x0a',
+          BlueFuzz: '\x0c\x0b',
+          BlueScale: '\x0c\x09',
+          LanguageGroup: '\x0c\x11',
+          ExpansionFactor:  '\x0c\x18'
+        };
+        for (var field in fieldMap) {
+          if (!properties.private.hasOwnProperty(field)) continue;
+          var value = properties.private[field];
+
+          if (IsArray(value)) {
+            data += self.encodeNumber(value[0]);
+            for (var i = 1; i < value.length; i++)
+              data += self.encodeNumber(value[i] - value[i - 1]);
+          } else {
+            data += self.encodeNumber(value);
+          }
+          data += fieldMap[field];
+        }
 
         data += self.encodeNumber(data.length + 4) + '\x13'; // Subrs offset