From a8ad07ccbfc0a2066f7624aad82d63d2f4070862 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 25 Jun 2013 10:33:53 -0700 Subject: [PATCH] Cache fonts by reference. --- src/core.js | 1 - src/evaluator.js | 49 +++++++++++++++++++++--------------- src/obj.js | 22 ++++++++++++++++ test/pdfs/issue2984.pdf.link | 2 ++ test/test_manifest.json | 9 +++++++ 5 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 test/pdfs/issue2984.pdf.link diff --git a/src/core.js b/src/core.js index 3437b9bfb..b795eb504 100644 --- a/src/core.js +++ b/src/core.js @@ -48,7 +48,6 @@ var Page = (function PageClosure() { this.xref = xref; this.ref = ref; this.idCounters = { - font: 0, obj: 0 }; this.resourcesPromise = null; diff --git a/src/evaluator.js b/src/evaluator.js index 592b78f3c..7fbf30963 100644 --- a/src/evaluator.js +++ b/src/evaluator.js @@ -19,7 +19,8 @@ IDENTITY_MATRIX, info, isArray, isCmd, isDict, isEOF, isName, isNum, isStream, isString, JpegStream, Lexer, Metrics, Name, Parser, Pattern, PDFImage, PDFJS, serifFonts, stdFontMap, symbolsFonts, - TilingPattern, TODO, warn, Util, MissingDataException, Promise */ + TilingPattern, TODO, warn, Util, MissingDataException, Promise, + RefSetCache, isRef */ 'use strict'; @@ -35,6 +36,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { this.pageIndex = pageIndex; this.uniquePrefix = uniquePrefix; this.idCounters = idCounters; + this.fontCache = new RefSetCache(); } // Specifies properties for each command @@ -502,38 +504,45 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { loadFont: function PartialEvaluator_loadFont(fontName, font, xref, resources) { - var promise = new Promise(); - - var fontRes = resources.get('Font'); - if (!fontRes) { - warn('fontRes not available'); - } - - font = xref.fetchIfRef(font) || (fontRes && fontRes.get(fontName)); - if (!isDict(font)) { - ++this.idCounters.font; + function errorFont(promise) { promise.resolve({ font: { translated: new ErrorFont('Font ' + fontName + ' is not available'), - loadedName: 'g_font_' + this.uniquePrefix + this.idCounters.obj + loadedName: 'g_font_error' }, dependencies: {} }); return promise; } - if (font.loaded) { - promise.resolve({ - font: font, - dependencies: {} - }); - return promise; + var fontRef; + if (font) { // Loading by ref. + assert(isRef(font)); + fontRef = font; + } else { // Loading by name. + var fontRes = resources.get('Font'); + if (fontRes) { + fontRef = fontRes.getRaw(fontName); + } else { + warn('fontRes not available'); + return errorFont(new Promise()); + } + } + if (this.fontCache.has(fontRef)) { + return this.fontCache.get(fontRef); + } + + var promise = new Promise(); + this.fontCache.put(fontRef, promise); + + font = xref.fetchIfRef(fontRef); + if (!isDict(font)) { + return errorFont(promise); } // keep track of each font we translated so the caller can // load them asynchronously before calling display on a page - font.loadedName = 'g_font_' + this.uniquePrefix + - (++this.idCounters.font); + font.loadedName = 'g_font_' + fontRef.num + '_' + fontRef.gen; if (!font.translated) { var translated; diff --git a/src/obj.js b/src/obj.js index 9df41af1c..6835ef8b4 100644 --- a/src/obj.js +++ b/src/obj.js @@ -187,6 +187,28 @@ var RefSet = (function RefSetClosure() { return RefSet; })(); +var RefSetCache = (function RefSetCacheClosure() { + function RefSetCache() { + this.dict = {}; + } + + RefSetCache.prototype = { + get: function RefSetCache_get(ref) { + return this.dict['R' + ref.num + '.' + ref.gen]; + }, + + has: function RefSetCache_has(ref) { + return ('R' + ref.num + '.' + ref.gen) in this.dict; + }, + + put: function RefSetCache_put(ref, obj) { + this.dict['R' + ref.num + '.' + ref.gen] = obj; + } + }; + + return RefSetCache; +})(); + var Catalog = (function CatalogClosure() { function Catalog(pdfManager, xref) { this.pdfManager = pdfManager; diff --git a/test/pdfs/issue2984.pdf.link b/test/pdfs/issue2984.pdf.link new file mode 100644 index 000000000..80eb6b5a1 --- /dev/null +++ b/test/pdfs/issue2984.pdf.link @@ -0,0 +1,2 @@ +http://computation.llnl.gov/casc/sapphire/pubs/denoising.pdf + diff --git a/test/test_manifest.json b/test/test_manifest.json index c3072484c..bc5fbaec7 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -1088,6 +1088,15 @@ "type": "eq", "about": "Has a 4 bit per component image with mask and decode." }, + { "id": "issue2984", + "file": "pdfs/issue2984.pdf", + "md5": "d41d8cd98f00b204e9800998ecf8427e", + "rounds": 1, + "link": true, + "type": "eq", + "lastPage": 1, + "about": "Type3 fonts with lots of switching between them." + }, { "id": "bug808084", "file": "pdfs/bug808084.pdf", "md5": "b1c400de699af29ea3f1983bb26870ab",