]> git.parisson.com Git - pdf.js.git/commitdiff
Add opentype ascender, descender and units-per-em to font properties
authorAdil Allawi <adil@diwan.com>
Fri, 16 Sep 2011 12:50:11 +0000 (13:50 +0100)
committerAdil Allawi <adil@diwan.com>
Fri, 16 Sep 2011 16:46:15 +0000 (17:46 +0100)
Prefer font ascender, descender when creating OS/2 table
scale PDF ascender and descender in OS/2 table by font units per em if it exists
Fix the truetype font header to prevent Windows rejecting a Mac truetype font

fonts.js

index 064702de2aa0169d43a49bb4f65bb2d46d592883..fd7a23bd30a777458d0ca8f6089216919953ca52 100644 (file)
--- a/fonts.js
+++ b/fonts.js
@@ -12,6 +12,9 @@ var kMaxWaitForFontFace = 1000;
 // Unicode Private Use Area
 var kCmapGlyphOffset = 0xE000;
 
+// PDF Glyph Space Units are one Thousandth of a TextSpace Unit except for Type 3 fonts
+var kPDFGlyphSpaceUnits = 1000;
+
 // Until hinting is fully supported this constant can be used
 var kHintingEnabled = false;
 
@@ -534,6 +537,10 @@ var Font = (function Font() {
   };
 
   function createOpenTypeHeader(sfnt, file, numTables) {
+    // Windows hates the Mac TrueType sfnt version number
+    if (sfnt == 'true')
+      sfnt = string32(0x00010000);
+
     // sfnt version (4 bytes)
     var header = sfnt;
 
@@ -694,6 +701,24 @@ var Font = (function Font() {
       }
     }
 
+    var openTypeUnitsPerEm = (typeof (properties.openTypeUnitsPerEm) == 'undefined') ? kPDFGlyphSpaceUnits : properties.openTypeUnitsPerEm;
+    var typoAscent = properties.ascent;
+    var typoDescent = properties.descent;
+    var winAscent = typoAscent;
+    var winDescent = -typoDescent;
+
+    // if the font already has ascent and descent information then use these values
+    if (typeof (properties.openTypeAscent) != 'undefined') {
+      typoAscent = properties.openTypeAscent;
+      typoDescent = properties.openTypeDescent;
+      winAscent = properties.openTypeYMax;
+      winDescent = -properties.openTypeYMin;
+    } else if (openTypeUnitsPerEm != kPDFGlyphSpaceUnits) {
+      // if the font units differ to the PDF glyph space units then scale up the values
+      typoAscent = Math.round(typoAscent * openTypeUnitsPerEm / kPDFGlyphSpaceUnits);
+      typoDescent = Math.round(typoDescent * openTypeUnitsPerEm / kPDFGlyphSpaceUnits);
+    }
+
     return '\x00\x03' + // version
            '\x02\x24' + // xAvgCharWidth
            '\x01\xF4' + // usWeightClass
@@ -722,11 +747,11 @@ var Font = (function Font() {
            string16(firstCharIndex ||
                     properties.firstChar) + // usFirstCharIndex
            string16(lastCharIndex || properties.lastChar) +  // usLastCharIndex
-           string16(properties.ascent) + // sTypoAscender
-           string16(properties.descent) + // sTypoDescender
+           string16(typoAscent) + // sTypoAscender
+           string16(typoDescent) + // sTypoDescender
            '\x00\x64' + // sTypoLineGap (7%-10% of the unitsPerEM value)
-           string16(properties.ascent) + // usWinAscent
-           string16(-properties.descent) + // usWinDescent
+           string16(winAscent) + // usWinAscent
+           string16(winDescent) + // usWinDescent
            '\x00\x00\x00\x00' + // ulCodePageRange1 (Bits 0-31)
            '\x00\x00\x00\x00' + // ulCodePageRange2 (Bits 32-63)
            string16(properties.xHeight) + // sxHeight
@@ -1047,18 +1072,19 @@ var Font = (function Font() {
         virtualOffset: numTables * (4 * 4)
       };
 
+      //extract some more font properties from the OpenType head and hhea tables
+      properties.openTypeUnitsPerEm = int16([head.data[18], head.data[19]]);
+      properties.openTypeYMax = int16([head.data[42], head.data[43]]);
+      properties.openTypeYMin = int16([head.data[38], head.data[39]]) - 0x10000;   //always negative
+      properties.openTypeAscent =  int16([hhea.data[4], hhea.data[5]]);
+      properties.openTypeDescent =  int16([hhea.data[6], hhea.data[7]]) - 0x10000;   //always negative
+
+
       // The new numbers of tables will be the last one plus the num
       // of missing tables
       createOpenTypeHeader(header.version, ttf, numTables);
 
       if (requiredTables.indexOf('OS/2') != -1) {
-        if (typeof(head) != 'undefined') {
-          var ymax = int16([head.data[42],head.data[43]]);
-          var ymin = int16([head.data[38],head.data[39]]) - 0x10000;   //always negative
-          properties.ascent = ymax;
-          properties.descent = ymin;
-        }
-
         tables.push({
           tag: 'OS/2',
           data: stringToArray(createOS2Table(properties))