From 363071aab90bb3d06305e27a98961d29c2de15f1 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Tue, 14 Jun 2011 21:38:59 +0200 Subject: [PATCH] Add XObjects fonts to the list of page fonts and has a forEach method to the Dict class --- PDFFont.js | 13 ++++++++++++ pdf.js | 34 +++++++++++++++++++++++-------- test.js | 60 +++++++++++++++++++++++------------------------------- 3 files changed, 64 insertions(+), 43 deletions(-) diff --git a/PDFFont.js b/PDFFont.js index 9c6c620bb..56e93c19a 100644 --- a/PDFFont.js +++ b/PDFFont.js @@ -580,9 +580,22 @@ var FontsUtils = { * and valid in the point of view of the sanitizer. */ var TrueType = function(aFile) { + var header = this._readOpenTypeHeader(aFile); this.data = aFile; }; +TrueType.prototype = { + _readOpenTypeHeader: function(aFile) { + return { + version: aFile.getBytes(4), + numTables: FontsUtils.bytesToInteger(aFile.getBytes(2)), + searchRange: FontsUtils.bytesToInteger(aFile.getBytes(2)), + entrySelector: FontsUtils.bytesToInteger(aFile.getBytes(2)), + rangeShift: FontsUtils.bytesToInteger(aFile.getBytes(2)) + } + } +}; + /** * This dictionary holds decoded fonts data. */ diff --git a/pdf.js b/pdf.js index bbfa7186a..afcb39fff 100644 --- a/pdf.js +++ b/pdf.js @@ -563,6 +563,10 @@ var Dict = (function() { set: function(key, value) { this.map[key] = value; }, + forEach: function(aCallback) { + for (var key in this.map) + aCallback(key, this.map[key]); + }, toString: function() { var keys = []; for (var key in this.map) @@ -1404,16 +1408,30 @@ var Page = (function() { }, get fonts() { var xref = this.xref; - var fonts = []; - var resources = xref.fetchIfRef(this.resources); - var fontResource = resources.get("Font"); - for (var id in fontResource.map) { - var res = xref.fetch(fontResource.get(id)); - var descriptor = xref.fetch(res.get("FontDescriptor")); - fonts.push(descriptor.get("FontName").toString()); + var fontsDict = new Dict(); + + // Get the fonts use on the page + var fontResources = resources.get("Font"); + fontResources.forEach(function(fontKey, fontData) { + fontsDict.set(fontKey, xref.fetch(fontData)) + }); + + // Get the fonts use on xobjects of the page if any + var xobjs = xref.fetchIfRef(resources.get("XObject")); + if (xobjs) { + xobjs.forEach(function(key, xobj) { + xobj = xref.fetchIfRef(xobj); + assertWellFormed(IsStream(xobj), "XObject should be a stream"); + + var xobjFonts = xobj.dict.get("Resources").get("Font"); + xobjFonts.forEach(function(fontKey, fontData) { + fontsDict.set(fontKey, xref.fetch(fontData)) + }); + }); } - return shadow(this, "fonts", fonts); + + return shadow(this, "fonts", fontsDict); }, display: function(gfx) { var xref = this.xref; diff --git a/test.js b/test.js index f2fdcfdf7..071b2f097 100644 --- a/test.js +++ b/test.js @@ -76,47 +76,37 @@ function displayPage(num) { // of the page to be fully loaded before loading the page var fontsReady = true; var fonts = page.fonts; - for (var i = 0; i < fonts.length; i++) { - var fontName = fonts[i].replace("+", "_"); - var font = Fonts[fontName]; - if (!font) { - // load the new font - var xref = page.xref; - var resources = xref.fetchIfRef(page.resources); - var fontResource = resources.get("Font"); - for (var id in fontResource.map) { - var res = xref.fetch(fontResource.get(id)); - var descriptor = xref.fetch(res.get("FontDescriptor")); - var name = descriptor.get("FontName").toString(); - if (name == fontName.replace("_", "+")) { - var subtype = res.get("Subtype").name; - var fontFile = page.xref.fetchIfRef(descriptor.get("FontFile")); - if (!fontFile) - fontFile = page.xref.fetchIfRef(descriptor.get("FontFile2")); + var xref = page.xref; + fonts.forEach(function(fontKey, fontDict) { + var descriptor = xref.fetch(fontDict.get("FontDescriptor")); + var fontName = descriptor.get("FontName").name; + fontName = fontName.replace("+", "_"); - // Generate the custom cmap of the font - var encoding = xref.fetch(res.get("Encoding")); - var differences = encoding.get("Differences"); + // Check if the font has been loaded or is still loading + var font = Fonts[fontName]; + if (!font) { + var fontFile = xref.fetchIfRef(descriptor.get2("FontFile", "FontFile2")); + // Generate the custom cmap of the font if needed var encodingMap = {}; - var index = 0; - for (var j = 0; j < differences.length; j++) { - var data = differences[j]; - if (IsNum(data)) - index = data; - else - encodingMap[index++] = data; + if (fontDict.has("Encoding")) { + var encoding = xref.fetchIfRef(fontDict.get("Encoding")); + if (IsDict(encoding)) { + var differences = encoding.get("Differences"); + var index = 0; + for (var j = 0; j < differences.length; j++) { + var data = differences[j]; + IsNum(data) ? index = data : encodingMap[index++] = data; + } + } } + var subtype = fontDict.get("Subtype").name; new Font(fontName, fontFile, encodingMap, subtype); - fontsReady = false; - break; - } + return fontsReady = false; + } else if (font.loading) { + return fontsReady = false; } - } else if (font.loading) { - fontsReady = false; - break; - } - } + }); // If everything is ready do not delayed the page loading any more if (fontsReady)