From c345a4c75e8383247c85bc5d75bba45a8c775a27 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Mon, 20 Jun 2011 08:20:31 +0200 Subject: [PATCH] Add more TrueType rewriting magic ('post' table) --- fonts.js | 38 +++++++++++++++++++++++++++++++++++--- pdf.js | 45 +++++++++++++++------------------------------ 2 files changed, 50 insertions(+), 33 deletions(-) diff --git a/fonts.js b/fonts.js index 72fabd2e3..172d6fa3c 100644 --- a/fonts.js +++ b/fonts.js @@ -23,6 +23,7 @@ var kMaxWaitForFontFace = 1000; * many fonts are loaded. */ var fontCount = 0; +var fontName = ""; /** * Hold a map of decoded fonts and of the standard fourteen Type1 fonts and @@ -38,6 +39,7 @@ var Fonts = { }, set active(aName) { + fontName = aName; this._active = this[aName]; }, @@ -694,7 +696,7 @@ var TrueType = function(aName, aFile, aProperties) { // If any tables are still in the array this means some required tables are // missing, which means that we need to rebuild the font in order to pass // the sanitizer. - if (requiredTables.length == 1 && requiredTables[0] == "OS/2") { + if (requiredTables.length && requiredTables[0] == "OS/2") { var OS2 = [ 0x00, 0x03, // version 0x02, 0x24, // xAvgCharWidth @@ -747,13 +749,43 @@ var TrueType = function(aName, aFile, aProperties) { // Replace the old CMAP table var rewrittedCMAP = this._createCMAPTable(glyphs); - var cmapDelta = rewrittedCMAP.length - originalCMAP.data.length; + var offsetDelta = rewrittedCMAP.length - originalCMAP.data.length; originalCMAP.data = rewrittedCMAP; + // Rewrite the 'post' table if needed + var postTable = null; + for (var i = 0; i < tables.length; i++) { + var table = tables[i]; + if (table.tag == "post") { + postTable = table; + break; + } + } + + if (!postTable) { + var post = [ + 0x00, 0x03, 0x00, 0x00, // Version number + 0x00, 0x00, 0x01, 0x00, // italicAngle + 0x00, 0x00, // underlinePosition + 0x00, 0x00, // underlineThickness + 0x00, 0x00, 0x00, 0x00, // isFixedPitch + 0x00, 0x00, 0x00, 0x00, // minMemType42 + 0x00, 0x00, 0x00, 0x00, // maxMemType42 + 0x00, 0x00, 0x00, 0x00, // minMemType1 + 0x00, 0x00, 0x00, 0x00 // maxMemType1 + ]; + + offsetDelta += post.length; + tables.unshift({ + tag: "post", + data: post + }); + } + // Create a new file to hold the new version of our truetype with a new // header and new offsets var stream = aFile.stream || aFile; - var ttf = new Uint8Array(stream.length + 16 + OS2.length + cmapDelta); + var ttf = new Uint8Array(stream.length + 1024); // The new numbers of tables will be the last one plus the num of missing // tables diff --git a/pdf.js b/pdf.js index 7414ac7ea..cc84115cf 100644 --- a/pdf.js +++ b/pdf.js @@ -1607,10 +1607,7 @@ var CanvasExtraState = (function() { const Encodings = { get ExpertEncoding() { - return shadow(this, "ExpertEncoding", [ - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, + return shadow(this, "ExpertEncoding", [ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, "space","exclamsmall","Hungarumlautsmall",,"dollaroldstyle","dollarsuperior", "ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior", "twodotenleader","onedotenleader","comma","hyphen","period","fraction", @@ -1645,10 +1642,7 @@ const Encodings = { ]); }, get MacExpertEncoding() { - return shadow(this, "MacExpertEncoding", [ - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, + return shadow(this, "MacExpertEncoding", [ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, "space","exclamsmall","Hungarumlautsmall","centoldstyle","dollaroldstyle", "dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior", "parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period", @@ -1682,10 +1676,7 @@ const Encodings = { ]); }, get MacRomanEncoding() { - return shadow(this, "MacRomanEncoding", [ - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, + return shadow(this, "MacRomanEncoding", [ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, "space","exclam","quotedbl","numbersign","dollar","percent","ampersand", "quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen", "period","slash","zero","one","two","three","four","five","six","seven","eight", @@ -1715,10 +1706,7 @@ const Encodings = { ]); }, get StandardEncoding() { - return shadow(this, "StandardEncoding", [ - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, + return shadow(this, "StandardEncoding", [ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, "space","exclam","quotedbl","numbersign","dollar","percent","ampersand", "quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period", "slash","zero","one","two","three","four","five","six","seven","eight","nine", @@ -1738,10 +1726,7 @@ const Encodings = { ]); }, get WinAnsiEncoding() { - return shadow(this, "WinAnsiEncoding", [ - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, + return shadow(this, "WinAnsiEncoding", [ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, "space","exclam","quotedbl","numbersign","dollar","percent","ampersand", "quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen", "period","slash","zero","one","two","three","four","five","six","seven","eight", @@ -1772,10 +1757,7 @@ const Encodings = { ]); }, get zapfDingbatsEncoding() { - return shadow(this, "zapfDingbatsEncoding", [ - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, + return shadow(this, "zapfDingbatsEncoding", [ ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, "space","a1","a2","a202","a3","a4","a5","a119","a118","a117","a11","a12","a13", "a14","a15","a16","a105","a17","a18","a19","a20","a21","a22","a23","a24","a25", "a26","a27","a28","a6","a7","a8","a9","a10","a29","a30","a31","a32","a33","a34", @@ -1918,13 +1900,12 @@ var CanvasGraphics = (function() { error("FontFile not found for font: " + fontName); fontFile = xref.fetchIfRef(fontFile); - // Generate the custom cmap of the font if needed var encodingMap = {}; var charset = []; if (fontDict.has("Encoding")) { var encoding = xref.fetchIfRef(fontDict.get("Encoding")); if (IsDict(encoding)) { - // Build an map between codes and glyphs + // Build a map between codes and glyphs var differences = encoding.get("Differences"); var index = 0; for (var j = 0; j < differences.length; j++) { @@ -1960,9 +1941,13 @@ var CanvasGraphics = (function() { } else if (fontDict.has("ToUnicode")) { var cmapObj = xref.fetchIfRef(fontDict.get("ToUnicode")); if (IsName(cmapObj)) { - error("ToUnicode basic cmap translation not implemented"); - encodingMap = {}; + error("ToUnicode file cmap translation not implemented"); } else if (IsStream(cmapObj)) { + var encoding = Encodings["WinAnsiEncoding"]; + var firstChar = xref.fetchIfRef(fontDict.get("FirstChar")); + for (var i = firstChar; i < encoding.length; i++) + encodingMap[i] = new Name(encoding[i]); + var tokens = []; var token = ""; @@ -1992,8 +1977,8 @@ var CanvasGraphics = (function() { var code = parseInt("0x" + tokens[j+2]); for (var k = startRange; k <= endRange; k++) { - encodingMap[k] = code; - charset.push(code++); + encodingMap[k] = GlyphsUnicode[encoding[code]]; + charset.push(encoding[code++]); } } break;