From b17a666343a07e1ba49e8039226ccb828d7fdc11 Mon Sep 17 00:00:00 2001 From: Adil Allawi Date: Tue, 5 Jul 2011 12:47:15 +0100 Subject: [PATCH 01/10] First pass CIDFont - stop CID fonts breaking PDF rendering --- pdf.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pdf.js b/pdf.js index c450b6ddd..9dddd8210 100644 --- a/pdf.js +++ b/pdf.js @@ -3626,9 +3626,17 @@ var PartialEvaluator = (function() { translateFont: function(fontDict, xref, resources) { var fd = fontDict.get('FontDescriptor'); if (!fd) - // XXX deprecated "special treatment" for standard - // fonts? What do we need to do here? - return null; + { + //If font is a composite get the FontDescriptor from the descendant + var df = fontDict.get("DescendantFonts"); + if (!df) + return null; + var descendant = xref.fetch(df[0]); + fd = descendant.get("FontDescriptor"); + if (!fd) + return null; + fontDict.set("FontDescriptor", fd); + } var descriptor = xref.fetch(fd); var fontName = descriptor.get('FontName'); @@ -3674,6 +3682,7 @@ var PartialEvaluator = (function() { } } else if (IsName(encoding)) { var encoding = Encodings[encoding.name]; + //XXX CIDFont support - get the CID Encoding especially support japan1 and identity if (!encoding) error('Unknown font encoding'); From ea2d651709739cc69e568982cff718ac3ea9a0be Mon Sep 17 00:00:00 2001 From: Adil Allawi Date: Fri, 1 Jul 2011 17:47:28 +0100 Subject: [PATCH 02/10] Ignore Aptana project files Ignore test file directory --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9e2d0f211..41d51f615 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ pdf.pdf intelisa.pdf openweb_tm-PRINT.pdf local.mk +.project +PDF JS font experiments \ No newline at end of file From 7b8542c6a7bb1c17bcf893a9413b2f8c969492e9 Mon Sep 17 00:00:00 2001 From: Adil Allawi Date: Mon, 11 Jul 2011 17:41:47 +0100 Subject: [PATCH 03/10] Second pass CIDFont support - make Arial Unicode in OpenOffice PDF - supports PDF fonts with CIDtoGIDMap and no cmap --- fonts.js | 108 +++++++++++++++++++++++++++++++++++++++---------------- pdf.js | 60 ++++++++++++++++++++++++------- 2 files changed, 125 insertions(+), 43 deletions(-) diff --git a/fonts.js b/fonts.js index 1f0a6a211..2728afd89 100755 --- a/fonts.js +++ b/fonts.js @@ -404,12 +404,21 @@ var Font = (function() { data = this.checkAndRepair(name, file, properties); break; + case 'Type0': + //this is a Truetype font + this.mimetype = 'font/opentype'; + + // Repair the TrueType file if it is can be damaged in the point of + // view of the sanitizer + data = this.checkAndRepair(name, file, properties); + break; + default: warn('Font ' + properties.type + ' is not supported'); break; } this.data = data; - + this.type = properties.type; //use the type to test if the string is single or multi-byte this.id = Fonts.registerFont(name, data, properties); this.loadedName = 'pdfFont' + this.id; }; @@ -856,8 +865,26 @@ var Font = (function() { data: stringToArray(createOS2Table(properties)) }); - // Replace the old CMAP table with a shiny new one - replaceCMapTable(cmap, font, properties); + if (!cmap) { + var glyphs = []; + var charset = properties.charset; + for (var i=1; i < charset.length; i++) { + if (charset.indexOf(i) != -1) { + glyphs.push({ + unicode: charset.indexOf(i) + }); + } else { + break; + } + } + tables.push({ + tag: 'cmap', + data: createCMapTable(glyphs) + }) + } else { + // Replace the old CMAP table with a shiny new one + replaceCMapTable(cmap, font, properties); + } // Rewrite the 'post' table if needed if (!post) { @@ -1110,44 +1137,63 @@ var Font = (function() { charsToUnicode: function fonts_chars2Unicode(chars) { var charsCache = this.charsCache; - + var str; + // if we translated this string before, just grab it from the cache if (charsCache) { - var str = charsCache[chars]; + str = charsCache[chars]; if (str) return str; } - - // translate the string using the font's encoding - var encoding = this.encoding; - if (!encoding) - return chars; - + // lazily create the translation cache if (!charsCache) charsCache = this.charsCache = Object.create(null); - - str = ''; - for (var i = 0; i < chars.length; ++i) { - var charcode = chars.charCodeAt(i); - var unicode = encoding[charcode]; - if ('undefined' == typeof(unicode)) { - // FIXME/issue 233: we're hitting this in test/pdf/sizes.pdf - // at the moment, for unknown reasons. - warn('Unencoded charcode '+ charcode); - unicode = charcode; + + if (this.type == "Type0") { + //string needs to be converted from byte to multi-byte assume for now two-byte + str = ''; + var multiByteStr = ""; + var length = chars.length; + for (var i = 0; i < length; i++) { + var byte1 = chars.charCodeAt(i++) & 0xFF; + var byte2; + if (i == length) + byte2 = 0; + else + byte2 = chars.charCodeAt(i) & 0xFF; + multiByteStr += String.fromCharCode((byte1<<8) | byte2); } - - // Check if the glyph has already been converted - if (!IsNum(unicode)) - unicode = encoding[unicode] = GlyphsUnicode[unicode.name]; - - // Handle surrogate pairs - if (unicode > 0xFFFF) { - str += String.fromCharCode(unicode & 0xFFFF); - unicode >>= 16; + str = multiByteStr; + } + else { + // translate the string using the font's encoding + var encoding = this.encoding; + if (!encoding) + return chars; + + str = ''; + for (var i = 0; i < chars.length; ++i) { + var charcode = chars.charCodeAt(i); + var unicode = encoding[charcode]; + if ('undefined' == typeof(unicode)) { + // FIXME/issue 233: we're hitting this in test/pdf/sizes.pdf + // at the moment, for unknown reasons. + warn('Unencoded charcode '+ charcode); + unicode = charcode; + } + + // Check if the glyph has already been converted + if (!IsNum(unicode)) + unicode = encoding[unicode] = GlyphsUnicode[unicode.name]; + + // Handle surrogate pairs + if (unicode > 0xFFFF) { + str += String.fromCharCode(unicode & 0xFFFF); + unicode >>= 16; + } + str += String.fromCharCode(unicode); } - str += String.fromCharCode(unicode); } // Enter the translated string into the cache diff --git a/pdf.js b/pdf.js index 9dddd8210..888addd1b 100644 --- a/pdf.js +++ b/pdf.js @@ -64,6 +64,14 @@ function stringToBytes(str) { return bytes; } +function singleByteToMultiByteString (str) { + var multiByteStr = ""; + var bytes = stringToBytes(e); + for (var j = 0; j Date: Mon, 11 Jul 2011 17:55:03 +0100 Subject: [PATCH 04/10] Add test files with CID fonts --- test/pdfs/arial_unicode_ab_cidfont.pdf | Bin 0 -> 13110 bytes test/pdfs/arial_unicode_en_cidfont.pdf | Bin 0 -> 15779 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/pdfs/arial_unicode_ab_cidfont.pdf create mode 100644 test/pdfs/arial_unicode_en_cidfont.pdf diff --git a/test/pdfs/arial_unicode_ab_cidfont.pdf b/test/pdfs/arial_unicode_ab_cidfont.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e5c97b882ac15cd0a1b3145ad5a2f18d1836edea GIT binary patch literal 13110 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 W?&k5kY`_pc2tOVRi>$gF-v0ryt_6w! literal 0 HcmV?d00001 diff --git a/test/pdfs/arial_unicode_en_cidfont.pdf b/test/pdfs/arial_unicode_en_cidfont.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6c90e41e3355ae54669445d85ce86ddaa7b6a813 GIT binary patch literal 15779 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 Date: Tue, 12 Jul 2011 03:58:09 +0100 Subject: [PATCH 05/10] cleanup, added new flag to the font properties called compositeFont. If true, the encoding and ShowText strings must be multi-byte --- fonts.js | 21 +++++++++------------ pdf.js | 53 +++++++++++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/fonts.js b/fonts.js index 2728afd89..3e6756624 100755 --- a/fonts.js +++ b/fonts.js @@ -389,6 +389,7 @@ var Font = (function() { var data; switch (properties.type) { case 'Type1': + case 'CIDFontType0': var cff = new CFF(name, file, properties); this.mimetype = 'font/opentype'; @@ -397,15 +398,7 @@ var Font = (function() { break; case 'TrueType': - this.mimetype = 'font/opentype'; - - // Repair the TrueType file if it is can be damaged in the point of - // view of the sanitizer - data = this.checkAndRepair(name, file, properties); - break; - - case 'Type0': - //this is a Truetype font + case 'CIDFontType2': this.mimetype = 'font/opentype'; // Repair the TrueType file if it is can be damaged in the point of @@ -421,6 +414,7 @@ var Font = (function() { this.type = properties.type; //use the type to test if the string is single or multi-byte this.id = Fonts.registerFont(name, data, properties); this.loadedName = 'pdfFont' + this.id; + this.compositeFont = properties.compositeFont; }; function stringToArray(str) { @@ -1150,8 +1144,11 @@ var Font = (function() { if (!charsCache) charsCache = this.charsCache = Object.create(null); - if (this.type == "Type0") { - //string needs to be converted from byte to multi-byte assume for now two-byte + if (this.compositeFont) { + // composite fonts have multi-byte strings + // convert the string from single-byte to multi-byte + // XXX assuming CIDFonts are two-byte - later need to extract the correct byte encoding + // according to the PDF spec str = ''; var multiByteStr = ""; var length = chars.length; @@ -1162,7 +1159,7 @@ var Font = (function() { byte2 = 0; else byte2 = chars.charCodeAt(i) & 0xFF; - multiByteStr += String.fromCharCode((byte1<<8) | byte2); + multiByteStr += String.fromCharCode((byte1 << 8) | byte2); } str = multiByteStr; } diff --git a/pdf.js b/pdf.js index 888addd1b..2df2f3f14 100644 --- a/pdf.js +++ b/pdf.js @@ -64,14 +64,6 @@ function stringToBytes(str) { return bytes; } -function singleByteToMultiByteString (str) { - var multiByteStr = ""; - var bytes = stringToBytes(e); - for (var j = 0; j Date: Tue, 12 Jul 2011 04:03:12 +0100 Subject: [PATCH 06/10] Revert "Ignore Aptana project files" This reverts commit ea2d651709739cc69e568982cff718ac3ea9a0be. --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 41d51f615..9e2d0f211 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,3 @@ pdf.pdf intelisa.pdf openweb_tm-PRINT.pdf local.mk -.project -PDF JS font experiments \ No newline at end of file From 36763e8e82fd47cec38d38b7c413edd80f082656 Mon Sep 17 00:00:00 2001 From: Adil Allawi Date: Wed, 13 Jul 2011 09:31:34 +0100 Subject: [PATCH 07/10] Fully support truetype composite fonts, clean up --- fonts.js | 182 +++++++++++++++++++++++++++++++++---------------------- pdf.js | 50 ++++++++------- 2 files changed, 137 insertions(+), 95 deletions(-) diff --git a/fonts.js b/fonts.js index 3e6756624..dfcda7af2 100755 --- a/fonts.js +++ b/fonts.js @@ -411,7 +411,7 @@ var Font = (function() { break; } this.data = data; - this.type = properties.type; //use the type to test if the string is single or multi-byte + this.type = properties.type; // Use the type to test if the string is single or multi-byte this.id = Fonts.registerFont(name, data, properties); this.loadedName = 'pdfFont' + this.id; this.compositeFont = properties.compositeFont; @@ -682,6 +682,65 @@ var Font = (function() { '\x00\x00\x00\x00'; // maxMemType1 }; + function createNameTable(name) { + var strings = [ + 'Original licence', // 0.Copyright + name, // 1.Font family + 'Unknown', // 2.Font subfamily (font weight) + 'uniqueID', // 3.Unique ID + name, // 4.Full font name + 'Version 0.11', // 5.Version + '', // 6.Postscript name + 'Unknown', // 7.Trademark + 'Unknown', // 8.Manufacturer + 'Unknown' // 9.Designer + ]; + + // Mac want 1-byte per character strings while Windows want + // 2-bytes per character, so duplicate the names table + var stringsUnicode = []; + for (var i = 0; i < strings.length; i++) { + var str = strings[i]; + + var strUnicode = ''; + for (var j = 0; j < str.length; j++) + strUnicode += string16(str.charCodeAt(j)); + stringsUnicode.push(strUnicode); + } + + var names = [strings, stringsUnicode]; + var platforms = ['\x00\x01', '\x00\x03']; + var encodings = ['\x00\x00', '\x00\x01']; + var languages = ['\x00\x00', '\x04\x09']; + + var namesRecordCount = strings.length * platforms.length; + var nameTable = + '\x00\x00' + // format + string16(namesRecordCount) + // Number of names Record + string16(namesRecordCount * 12 + 6); // Storage + + // Build the name records field + var strOffset = 0; + for (var i = 0; i < platforms.length; i++) { + var strs = names[i]; + for (var j = 0; j < strs.length; j++) { + var str = strs[j]; + var nameRecord = + platforms[i] + // platform ID + encodings[i] + // encoding ID + languages[i] + // language ID + string16(j) + // name ID + string16(str.length) + + string16(strOffset); + nameTable += nameRecord; + strOffset += str.length; + } + } + + nameTable += strings.join('') + stringsUnicode.join(''); + return nameTable; + } + constructor.prototype = { name: null, font: null, @@ -814,7 +873,7 @@ var Font = (function() { // This keep a reference to the CMap and the post tables since they can // be rewritted - var cmap, post; + var cmap, post, nameTable, maxp; var tables = []; for (var i = 0; i < numTables; i++) { @@ -825,6 +884,10 @@ var Font = (function() { cmap = table; else if (table.tag == 'post') post = table; + else if (table.tag == 'name') + nameTable = table; + else if (table.tag == 'maxp') + maxp = table; requiredTables.splice(index, 1); } @@ -859,24 +922,50 @@ var Font = (function() { data: stringToArray(createOS2Table(properties)) }); - if (!cmap) { + // Replace the old CMAP table with a shiny new one + if (properties.type == 'CIDFontType2') { + // Type2 composite fonts map charcters directly to glyphs so the cmap + // table must be replaced. + var glyphs = []; var charset = properties.charset; - for (var i=1; i < charset.length; i++) { - if (charset.indexOf(i) != -1) { + if (charset.length == 0) + { + // PDF did not contain a GIDMap for the font so create an identity cmap + + // First get the number of glyphs from the maxp table + font.pos = (font.start ? font.start : 0) + maxp.length; + var version = int16(font.getBytes(4)); + var numGlyphs = int16(font.getBytes(2)); + + // Now create an identity mapping + for (var i=1; i < numGlyphs; i++) { glyphs.push({ - unicode: charset.indexOf(i) + unicode: i }); - } else { - break; + } + } else { + for (var i=1; i < charset.length; i++) { + if (charset.indexOf(i) != -1) { + glyphs.push({ + unicode: charset.indexOf(i) + }); + } else { + break; + } } } - tables.push({ - tag: 'cmap', - data: createCMapTable(glyphs) - }) + + if (!cmap) { + // Font did not contain a cmap + tables.push({ + tag: 'cmap', + data: createCMapTable(glyphs) + }) + } else { + cmap.data = createCMapTable(glyphs); + } } else { - // Replace the old CMAP table with a shiny new one replaceCMapTable(cmap, font, properties); } @@ -888,6 +977,14 @@ var Font = (function() { }); } + // Rewrite the 'name' table if needed + if (!nameTable) { + tables.push({ + tag: 'name', + data: stringToArray(createNameTable(this.name)) + }); + } + // Tables needs to be written by ascendant alphabetic order tables.sort(function tables_sort(a, b) { return (a.tag > b.tag) - (a.tag < b.tag); @@ -930,65 +1027,6 @@ var Font = (function() { }, convert: function font_convert(fontName, font, properties) { - function createNameTable(name) { - var strings = [ - 'Original licence', // 0.Copyright - name, // 1.Font family - 'Unknown', // 2.Font subfamily (font weight) - 'uniqueID', // 3.Unique ID - name, // 4.Full font name - 'Version 0.11', // 5.Version - '', // 6.Postscript name - 'Unknown', // 7.Trademark - 'Unknown', // 8.Manufacturer - 'Unknown' // 9.Designer - ]; - - // Mac want 1-byte per character strings while Windows want - // 2-bytes per character, so duplicate the names table - var stringsUnicode = []; - for (var i = 0; i < strings.length; i++) { - var str = strings[i]; - - var strUnicode = ''; - for (var j = 0; j < str.length; j++) - strUnicode += string16(str.charCodeAt(j)); - stringsUnicode.push(strUnicode); - } - - var names = [strings, stringsUnicode]; - var platforms = ['\x00\x01', '\x00\x03']; - var encodings = ['\x00\x00', '\x00\x01']; - var languages = ['\x00\x00', '\x04\x09']; - - var namesRecordCount = strings.length * platforms.length; - var nameTable = - '\x00\x00' + // format - string16(namesRecordCount) + // Number of names Record - string16(namesRecordCount * 12 + 6); // Storage - - // Build the name records field - var strOffset = 0; - for (var i = 0; i < platforms.length; i++) { - var strs = names[i]; - for (var j = 0; j < strs.length; j++) { - var str = strs[j]; - var nameRecord = - platforms[i] + // platform ID - encodings[i] + // encoding ID - languages[i] + // language ID - string16(j) + // name ID - string16(str.length) + - string16(strOffset); - nameTable += nameRecord; - strOffset += str.length; - } - } - - nameTable += strings.join('') + stringsUnicode.join(''); - return nameTable; - } - function isFixedPitch(glyphs) { for (var i = 0; i < glyphs.length - 1; i++) { if (glyphs[i] != glyphs[i + 1]) diff --git a/pdf.js b/pdf.js index c73558abb..1680c1c59 100644 --- a/pdf.js +++ b/pdf.js @@ -3630,7 +3630,7 @@ var PartialEvaluator = (function() { var compositeFont = false; assertWellFormed(IsName(subType), 'invalid font Subtype'); - //If font is a composite + // If font is a composite // - get the descendant font // - set the type according to the descendant font // - get the FontDescriptor from the descendant font @@ -3664,31 +3664,35 @@ var PartialEvaluator = (function() { var encodingMap = {}; var charset = []; if (compositeFont) { - //Special CIDFont support - //XXX only identity CID Encodings supported for now - var encoding = xref.fetchIfRef(fontDict.get('Encoding')); - if (IsName(encoding)) { - //Encoding is a predefined CMap - if (encoding.name == 'Identity-H') { - if (subType.name == 'CIDFontType2') { - var cidToGidMap = descendant.get('CIDToGIDMap'); - if (cidToGidMap) { - //Extract the charset from the CIDToGIDMap - var glyphsStream = xref.fetchIfRef(cidToGidMap); - var glyphsData = glyphsStream.getBytes(0); - var i = 0; - //glyph ids are big-endian 2-byte values - for (var j=0; j Date: Wed, 13 Jul 2011 09:38:39 +0100 Subject: [PATCH 08/10] Bump up the max font file size. Composite fonts can be larger than simple fonts. Once we support Japanese we will need to reconsider how this is done as a large Japanese font may be up to 30Mb in size. --- fonts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fonts.js b/fonts.js index dfcda7af2..a048e78d8 100755 --- a/fonts.js +++ b/fonts.js @@ -7,7 +7,7 @@ var isWorker = (typeof window == 'undefined'); /** * Maximum file size of the font. */ -var kMaxFontFileSize = 40000; +var kMaxFontFileSize = 200000; /** * Maximum time to wait for a font to be loaded by font-face rules. From 8dbbbbb589246e2a06ec7a474939b6f7e7c23abf Mon Sep 17 00:00:00 2001 From: Adil Allawi Date: Wed, 13 Jul 2011 09:55:13 +0100 Subject: [PATCH 09/10] Add and wire in test files --- test/pdfs/ArabicCIDTrueType.pdf | Bin 0 -> 39370 bytes test/test_manifest.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 test/pdfs/ArabicCIDTrueType.pdf diff --git a/test/pdfs/ArabicCIDTrueType.pdf b/test/pdfs/ArabicCIDTrueType.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0821ccdbd7616c4fcbcf6e476ab8a1595c2b15cb GIT binary patch literal 39370 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 sYi5>`mTHt{Xr7X6VvuA Date: Wed, 13 Jul 2011 17:46:48 +0100 Subject: [PATCH 10/10] nits, picked --- fonts.js | 16 ++++++++-------- pdf.js | 3 +-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/fonts.js b/fonts.js index a048e78d8..607e2aab9 100755 --- a/fonts.js +++ b/fonts.js @@ -411,7 +411,7 @@ var Font = (function() { break; } this.data = data; - this.type = properties.type; // Use the type to test if the string is single or multi-byte + this.type = properties.type; this.id = Fonts.registerFont(name, data, properties); this.loadedName = 'pdfFont' + this.id; this.compositeFont = properties.compositeFont; @@ -924,13 +924,12 @@ var Font = (function() { // Replace the old CMAP table with a shiny new one if (properties.type == 'CIDFontType2') { - // Type2 composite fonts map charcters directly to glyphs so the cmap + // Type2 composite fonts map characters directly to glyphs so the cmap // table must be replaced. var glyphs = []; var charset = properties.charset; - if (charset.length == 0) - { + if (!charset.length) { // PDF did not contain a GIDMap for the font so create an identity cmap // First get the number of glyphs from the maxp table @@ -939,16 +938,17 @@ var Font = (function() { var numGlyphs = int16(font.getBytes(2)); // Now create an identity mapping - for (var i=1; i < numGlyphs; i++) { + for (var i = 1; i < numGlyphs; i++) { glyphs.push({ unicode: i }); } } else { - for (var i=1; i < charset.length; i++) { - if (charset.indexOf(i) != -1) { + for (var i = 1; i < charset.length; i++) { + var index = charset.indexOf(i); + if (index != -1) { glyphs.push({ - unicode: charset.indexOf(i) + unicode: index }); } else { break; diff --git a/pdf.js b/pdf.js index 1680c1c59..a3179406c 100644 --- a/pdf.js +++ b/pdf.js @@ -3634,8 +3634,7 @@ var PartialEvaluator = (function() { // - get the descendant font // - set the type according to the descendant font // - get the FontDescriptor from the descendant font - if (subType.name == 'Type0') - { + if (subType.name == 'Type0') { var df = fontDict.get('DescendantFonts'); if (!df) return null;