From 8ac2367fa0f2434bbc51995b6430cb8bf2cda7d3 Mon Sep 17 00:00:00 2001 From: sbarman Date: Thu, 7 Jul 2011 16:48:04 -0700 Subject: [PATCH 1/5] not refer fonts by name, instead use id --- fonts.js | 77 +++++++++++++++++++++++++++++++------------------------- pdf.js | 22 ++++++++-------- 2 files changed, 54 insertions(+), 45 deletions(-) diff --git a/fonts.js b/fonts.js index 2f6a550f8..d068e6714 100755 --- a/fonts.js +++ b/fonts.js @@ -24,17 +24,18 @@ var kMaxWaitForFontFace = 1000; var Fonts = (function Fonts() { var kScalePrecision = 40; - var fonts = Object.create(null); + var fonts = []; if (!isWorker) { var ctx = document.createElement('canvas').getContext('2d'); ctx.scale(1 / kScalePrecision, 1); } - function Font(name, data, properties) { + function FontInfo(name, data, properties, id) { this.name = name; this.data = data; this.properties = properties; + this.id = id; this.loading = true; this.charsCache = Object.create(null); this.sizes = []; @@ -44,27 +45,31 @@ var Fonts = (function Fonts() { var charsCache; var measureCache; + var fontCount = 0; + return { registerFont: function fonts_registerFont(fontName, data, properties) { - fonts[fontName] = new Font(fontName, data, properties); + fonts.push(new FontInfo(fontName, data, properties, fontCount)); + return fontCount++; }, blacklistFont: function fonts_blacklistFont(fontName) { - registerFont(fontName, null, {}); + var id = registerFont(fontName, null, {}); markLoaded(fontName); + return id; }, - lookup: function fonts_lookup(fontName) { - return fonts[fontName]; + lookupById: function fonts_lookupById(id) { + return fonts[id]; }, - setActive: function fonts_setActive(fontName, size) { + setActive: function fonts_setActive(font, size) { // |current| can be null is fontName is a built-in font // (e.g. "sans-serif") - if ((current = fonts[fontName])) { + if ((current = fonts[font.id])) { charsCache = current.charsCache; var sizes = current.sizes; if (!(measureCache = sizes[size])) measureCache = sizes[size] = Object.create(null); } - ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"'; + ctx.font = (size * kScalePrecision) + 'px "' + font.loadedName + '"'; }, charsToUnicode: function fonts_chars2Unicode(chars) { if (!charsCache) @@ -118,8 +123,8 @@ var FontLoader = { bind: function(fonts, callback) { function checkFontsLoaded() { for (var i = 0; i < fonts.length; i++) { - var font = fonts[i]; - if (Fonts.lookup(font.name).loading) { + var id = fonts[i].fontDict.fontObj.id; + if (Fonts.lookupById(id).loading) { return false; } } @@ -131,28 +136,29 @@ var FontLoader = { return true; } - var rules = [], names = []; + var rules = [], names = [], ids = []; for (var i = 0; i < fonts.length; i++) { var font = fonts[i]; - if (!Fonts.lookup(font.name)) { - var obj = new Font(font.name, font.file, font.properties); - var str = ''; - var data = Fonts.lookup(font.name).data; - var length = data.length; - for (var j = 0; j < length; j++) - str += String.fromCharCode(data[j]); + var obj = new Font(font.name, font.file, font.properties); + font.fontDict.fontObj = obj; - var rule = isWorker ? obj.bindWorker(str) : obj.bindDOM(str); - if (rule) { - rules.push(rule); - names.push(font.name); - } + var str = ''; + var data = Fonts.lookupById(obj.id).data; + var length = data.length; + for (var j = 0; j < length; j++) + str += String.fromCharCode(data[j]); + + var rule = isWorker ? obj.bindWorker(str) : obj.bindDOM(str); + if (rule) { + rules.push(rule); + names.push(obj.loadedName); + ids.push(obj.id); } } if (!isWorker && rules.length) { - FontLoader.prepareFontLoadEvent(rules, names); + FontLoader.prepareFontLoadEvent(rules, names, ids); } if (!checkFontsLoaded()) { @@ -167,7 +173,7 @@ var FontLoader = { // loaded in a subdocument. It's expected that the load of |rules| // has already started in this (outer) document, so that they should // be ordered before the load in the subdocument. - prepareFontLoadEvent: function(rules, names) { + prepareFontLoadEvent: function(rules, names, ids) { /** Hack begin */ // There's no event when a font has finished downloading so the // following code is a dirty hack to 'guess' when a font is @@ -209,7 +215,7 @@ var FontLoader = { function(e) { var fontNames = JSON.parse(e.data); for (var i = 0; i < fontNames.length; ++i) { - var font = Fonts.lookup(fontNames[i]); + var font = Fonts.lookupById(ids[i]); font.loading = false; } var evt = document.createEvent('Events'); @@ -402,15 +408,16 @@ var Font = (function() { this.encoding = properties.encoding; // If the font has already been decoded simply return it - if (Fonts.lookup(name)) { - this.font = Fonts.lookup(name).data; - return; - } + //if (Fonts.lookup(name)) { + // this.font = Fonts.lookup(name).data; + // return; + //} // If the font is to be ignored, register it like an already loaded font // to avoid the cost of waiting for it be be loaded by the platform. if (properties.ignore) { - Fonts.blacklistFont(name); + this.id = Fonts.blacklistFont(name); + this.loadedName = 'pdfFont' + this.id; return; } @@ -437,7 +444,9 @@ var Font = (function() { break; } this.data = data; - Fonts.registerFont(name, data, properties); + + this.id = Fonts.registerFont(name, data, properties); + this.loadedName = 'pdfFont' + this.id; }; function stringToArray(str) { @@ -1124,7 +1133,7 @@ var Font = (function() { }, bindDOM: function font_bindDom(data) { - var fontName = this.name; + var fontName = this.loadedName; // Add the font-face rule to the document var url = ('url(data:' + this.mimetype + ';base64,' + diff --git a/pdf.js b/pdf.js index d41a98c27..64a25210f 100644 --- a/pdf.js +++ b/pdf.js @@ -3605,9 +3605,10 @@ var CanvasGraphics = (function() { return { name: fontName, - file: fontFile, - properties: properties - }; + fontDict: fontDict, + file: fontFile, + properties: properties + }; }, beginDrawing: function(mediaBox) { @@ -3686,6 +3687,7 @@ var CanvasGraphics = (function() { var font = xref.fetchIfRef(fontRes.get(args[0].name)); assertWellFormed(IsDict(font)); if (!font.translated) { + // sbarman marker font.translated = this.translateFont(font, xref, resources); if (fonts && font.translated) { // keep track of each font we translated so the caller can @@ -3868,25 +3870,23 @@ var CanvasGraphics = (function() { return; var fontName = ''; - var fontDescriptor = font.get('FontDescriptor'); - if (fontDescriptor && fontDescriptor.num) { - var fontDescriptor = this.xref.fetchIfRef(fontDescriptor); - fontName = fontDescriptor.get('FontName').name.replace('+', '_'); - } + var fontObj = font.fontObj; + if (fontObj) + fontName = fontObj.loadedName; if (!fontName) { // TODO: fontDescriptor is not available, fallback to default font fontName = 'sans-serif'; } - this.current.fontName = fontName; + this.current.font = fontObj; this.current.fontSize = size; if (this.ctx.$setFont) { this.ctx.$setFont(fontName, size); } else { this.ctx.font = size + 'px "' + fontName + '"'; - Fonts.setActive(fontName, size); + Fonts.setActive(font, size); } }, setTextRenderingMode: function(mode) { @@ -3931,7 +3931,7 @@ var CanvasGraphics = (function() { text = Fonts.charsToUnicode(text); this.ctx.translate(this.current.x, -1 * this.current.y); - var font = Fonts.lookup(this.current.fontName); + var font = Fonts.lookupById(this.current.font.id); if (font && font.properties.textMatrix) this.ctx.transform.apply(this.ctx, font.properties.textMatrix); From c39eae3ce932832e1275ec0b1f3fec5226390cc6 Mon Sep 17 00:00:00 2001 From: sbarman Date: Thu, 7 Jul 2011 17:15:53 -0700 Subject: [PATCH 2/5] fixed up minor bugs --- fonts.js | 28 +++++++++++++--------------- pdf.js | 3 +-- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/fonts.js b/fonts.js index d068e6714..48c99d8a7 100755 --- a/fonts.js +++ b/fonts.js @@ -31,11 +31,13 @@ var Fonts = (function Fonts() { ctx.scale(1 / kScalePrecision, 1); } - function FontInfo(name, data, properties, id) { + var fontCount = 0; + + function FontInfo(name, data, properties) { this.name = name; this.data = data; this.properties = properties; - this.id = id; + this.id = fontCount++; this.loading = true; this.charsCache = Object.create(null); this.sizes = []; @@ -45,12 +47,11 @@ var Fonts = (function Fonts() { var charsCache; var measureCache; - var fontCount = 0; - return { registerFont: function fonts_registerFont(fontName, data, properties) { - fonts.push(new FontInfo(fontName, data, properties, fontCount)); - return fontCount++; + var font = new FontInfo(fontName, data, properties); + fonts.push(font); + return font.id; }, blacklistFont: function fonts_blacklistFont(fontName) { var id = registerFont(fontName, null, {}); @@ -122,8 +123,8 @@ var FontLoader = { bind: function(fonts, callback) { function checkFontsLoaded() { - for (var i = 0; i < fonts.length; i++) { - var id = fonts[i].fontDict.fontObj.id; + for (var i = 0; i < allIds.length; i++) { + var id = allIds[i]; if (Fonts.lookupById(id).loading) { return false; } @@ -136,12 +137,15 @@ var FontLoader = { return true; } + var allIds = []; var rules = [], names = [], ids = []; + for (var i = 0; i < fonts.length; i++) { var font = fonts[i]; var obj = new Font(font.name, font.file, font.properties); font.fontDict.fontObj = obj; + allIds.push(obj.id); var str = ''; var data = Fonts.lookupById(obj.id).data; @@ -160,7 +164,7 @@ var FontLoader = { if (!isWorker && rules.length) { FontLoader.prepareFontLoadEvent(rules, names, ids); } - + if (!checkFontsLoaded()) { document.documentElement.addEventListener( 'pdfjsFontLoad', checkFontsLoaded, false); @@ -407,12 +411,6 @@ var Font = (function() { this.name = name; this.encoding = properties.encoding; - // If the font has already been decoded simply return it - //if (Fonts.lookup(name)) { - // this.font = Fonts.lookup(name).data; - // return; - //} - // If the font is to be ignored, register it like an already loaded font // to avoid the cost of waiting for it be be loaded by the platform. if (properties.ignore) { diff --git a/pdf.js b/pdf.js index 64a25210f..a2526f362 100644 --- a/pdf.js +++ b/pdf.js @@ -3687,7 +3687,6 @@ var CanvasGraphics = (function() { var font = xref.fetchIfRef(fontRes.get(args[0].name)); assertWellFormed(IsDict(font)); if (!font.translated) { - // sbarman marker font.translated = this.translateFont(font, xref, resources); if (fonts && font.translated) { // keep track of each font we translated so the caller can @@ -3886,7 +3885,7 @@ var CanvasGraphics = (function() { this.ctx.$setFont(fontName, size); } else { this.ctx.font = size + 'px "' + fontName + '"'; - Fonts.setActive(font, size); + Fonts.setActive(fontObj, size); } }, setTextRenderingMode: function(mode) { From 619a5216787f47e79fdf3647b9c37007b10324c7 Mon Sep 17 00:00:00 2001 From: sbarman Date: Thu, 7 Jul 2011 17:37:27 -0700 Subject: [PATCH 3/5] minor fix --- fonts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fonts.js b/fonts.js index 48c99d8a7..262746ac6 100755 --- a/fonts.js +++ b/fonts.js @@ -1124,7 +1124,7 @@ var Font = (function() { action: 'font', data: { raw: data, - fontName: this.name, + fontName: this.loadedName, mimetype: this.mimetype } }); From 44048712126d57b9cb652e229406867ae5e5105f Mon Sep 17 00:00:00 2001 From: sbarman Date: Fri, 8 Jul 2011 08:14:34 -0700 Subject: [PATCH 4/5] fixed font loading bug --- fonts.js | 11 ++++++----- pdf.js | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/fonts.js b/fonts.js index 262746ac6..c275227a9 100755 --- a/fonts.js +++ b/fonts.js @@ -61,16 +61,16 @@ var Fonts = (function Fonts() { lookupById: function fonts_lookupById(id) { return fonts[id]; }, - setActive: function fonts_setActive(font, size) { + setActive: function fonts_setActive(fontName, fontObj, size) { // |current| can be null is fontName is a built-in font // (e.g. "sans-serif") - if ((current = fonts[font.id])) { + if (fontObj && (current = fonts[fontObj.id])) { charsCache = current.charsCache; var sizes = current.sizes; if (!(measureCache = sizes[size])) measureCache = sizes[size] = Object.create(null); } - ctx.font = (size * kScalePrecision) + 'px "' + font.loadedName + '"'; + ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"'; }, charsToUnicode: function fonts_chars2Unicode(chars) { if (!charsCache) @@ -161,6 +161,7 @@ var FontLoader = { } } + this.listeningForFontLoad = false; if (!isWorker && rules.length) { FontLoader.prepareFontLoadEvent(rules, names, ids); } @@ -213,7 +214,7 @@ var FontLoader = { div.innerHTML = html; document.body.appendChild(div); - if (!this.listeneningForFontLoad) { + if (!this.listeningForFontLoad) { window.addEventListener( 'message', function(e) { @@ -227,7 +228,7 @@ var FontLoader = { document.documentElement.dispatchEvent(evt); }, false); - this.listeneningForFontLoad = true; + this.listeningForFontLoad = true; } // XXX we should have a time-out here too, and maybe fire diff --git a/pdf.js b/pdf.js index a2526f362..c30c89614 100644 --- a/pdf.js +++ b/pdf.js @@ -3885,7 +3885,7 @@ var CanvasGraphics = (function() { this.ctx.$setFont(fontName, size); } else { this.ctx.font = size + 'px "' + fontName + '"'; - Fonts.setActive(fontObj, size); + Fonts.setActive(fontName, fontObj, size); } }, setTextRenderingMode: function(mode) { From 7b659fd605cc76dc7c86d3ae95076434630c8961 Mon Sep 17 00:00:00 2001 From: sbarman Date: Fri, 8 Jul 2011 10:04:52 -0700 Subject: [PATCH 5/5] fixed case when font cannot be found --- fonts.js | 4 ++++ pdf.js | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/fonts.js b/fonts.js index c275227a9..093b9ec31 100755 --- a/fonts.js +++ b/fonts.js @@ -69,7 +69,11 @@ var Fonts = (function Fonts() { var sizes = current.sizes; if (!(measureCache = sizes[size])) measureCache = sizes[size] = Object.create(null); + } else { + charsCache = null; + measureCache = null } + ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"'; }, charsToUnicode: function fonts_chars2Unicode(chars) { diff --git a/pdf.js b/pdf.js index c30c89614..85490baee 100644 --- a/pdf.js +++ b/pdf.js @@ -3930,10 +3930,12 @@ var CanvasGraphics = (function() { text = Fonts.charsToUnicode(text); this.ctx.translate(this.current.x, -1 * this.current.y); - var font = Fonts.lookupById(this.current.font.id); - if (font && font.properties.textMatrix) - this.ctx.transform.apply(this.ctx, font.properties.textMatrix); - + var font = this.current.font; + if (font) { + var fontInfo = Fonts.lookupById(font.id); + if (fontInfo && fontInfo.properties.textMatrix) + this.ctx.transform.apply(this.ctx, fontInfo.properties.textMatrix); + } this.ctx.fillText(text, 0, 0); this.current.x += Fonts.measureText(text); }