From e6bd3d8105a94e2441e62d507492da110d5f8c01 Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Sat, 1 Oct 2011 11:44:01 +0200 Subject: [PATCH] Backup --- fonts.js | 193 ++++++++++++++++++++++++++---------------------------- pdf.js | 23 ++++--- worker.js | 25 +++++-- 3 files changed, 124 insertions(+), 117 deletions(-) diff --git a/fonts.js b/fonts.js index 0de8fd379..3fce351a0 100755 --- a/fonts.js +++ b/fonts.js @@ -184,86 +184,6 @@ if (!isWorker) { */ var FontLoader = { listeningForFontLoad: false, - - scratchCtx: null, - loading: {}, - - /** - * Create the canvas used for measuring the width of text. - */ - setup: function() { - var canvas = document.createElement("canvas"); - var ctx = canvas.getContext("2d"); - this.ctx = ctx; - }, - - /** - * Measures the width of some string using a fontObj and some different - * fallback fonts. - */ - measure: function(fontObj, str) { - var ctx = this.ctx; - - // THe fonts used as fallback. - var fallbacks = [ "Arial", "Courier" ]; - - var widths = []; - for (var n = 0; n < fallbacks.length; n++) { - // Choose a large font size as there are no sub-pixel returned from - // measureText. - var font = fontObj.getRule(420, fallbacks[n]); - ctx.font = font; - - widths.push(ctx.measureText(str).width); - } - return widths; - }, - - /** - * Attaches a fontObj to the DOM and calls Objects.resolve(objId) once - * the font is loaded. - */ - bindWebKit: function(objId, fontObj) { - this.loading[objId] = true; - var encoding = fontObj.encoding; - - // If the font has an encoding, build the test string based on it. If the - // font doesn't have an encoding, the font can't been used right now and - // we skip here. - if (fontObj.supported) { - var testStr = ""; - for (var enc in encoding) { - testStr += String.fromCharCode(encoding[enc].unicode); - } - } else { - // This font isn't fully supported yet. Resolve the object such that - // the execution continues but do nothing else. - Objects.resolve(objId); - return; - } - - var before = this.measure(fontObj, testStr); - this.bindDOM(fontObj); - - var start = Date.now(); - var check = function() { - var measure = this.measure(fontObj, testStr); - - for (var i = 0; i < measure.length; i++) { - if (measure[i] !== before[i]) { - console.log("loaded font", objId, before, measure, Date.now() - start); - delete this.loading[objId]; - Objects.resolve(objId); - return; - } - } - - setTimeout(check, 0); - }.bind(this); - - // Start checking if font is loaded. - check(); - }, /** * Attach the fontObj to the DOM. @@ -290,14 +210,50 @@ var FontLoader = { return rule; }, - bind: function(fontObj) { - // If this isn't Gecko, we assume it's WebKit. See notes in bindWebKit. - if (!isGecko) { - this.bindWebKit(fontObj.loadedName, fontObj); - } else { - var rule = this.bindDOM(fontObj); - FontLoader.prepareFontLoadEvent(fontObj, rule); + bind: function fontLoaderBind(fonts, callback) { + function checkFontsLoaded() { + for (var i = 0; i < objs.length; i++) { + var fontObj = objs[i]; + if (fontObj.loading) { + return false; + } + } + + document.documentElement.removeEventListener( + 'pdfjsFontLoad', checkFontsLoaded, false); + + callback(); + return true; } + + var rules = [], names = [], objs = []; + + for (var i = 0; i < fonts.length; i++) { + var font = fonts[i]; + + // If there is no string on the font, then the font can't get loaded / + // get attached to the DOM. Skip this font. + if (!font.str) { + continue; + } + + objs.push(font); + + rules.push(this.bindDOM(font)); + names.push(font.loadedName); + } + + this.listeningForFontLoad = false; + if (!isWorker && rules.length) { + FontLoader.prepareFontLoadEvent(rules, names, objs); + } + + if (!checkFontsLoaded()) { + document.documentElement.addEventListener( + 'pdfjsFontLoad', checkFontsLoaded, false); + } + + return objs; }, // Set things up so that at least one pdfjsFontLoad event is @@ -305,7 +261,8 @@ 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(fontObj, rule) { + prepareFontLoadEvent: function fontLoaderPrepareFontLoadEvent(rules, names, + objs) { /** 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 @@ -329,15 +286,56 @@ var FontLoader = { // The postMessage() hackery was added to work around chrome bug // 82402. + var div = document.createElement('div'); + div.setAttribute('style', + 'visibility: hidden;' + + 'width: 10px; height: 10px;' + + 'position: absolute; top: 0px; left: 0px;'); + var html = ''; + for (var i = 0; i < names.length; ++i) { + html += 'Hi'; + } + div.innerHTML = html; + document.body.appendChild(div); + + if (!this.listeningForFontLoad) { + window.addEventListener( + 'message', + function fontLoaderMessage(e) { + var fontNames = JSON.parse(e.data); + for (var i = 0; i < objs.length; ++i) { + var font = objs[i]; + font.loading = false; + } + var evt = document.createEvent('Events'); + evt.initEvent('pdfjsFontLoad', true, false); + document.documentElement.dispatchEvent(evt); + }, + false); + this.listeningForFontLoad = true; + } + // XXX we should have a time-out here too, and maybe fire // pdfjsFontLoadFailed? var src = ''; src += ''; - src += ''; - src += ''; - src += '

Hi

' + src += ''; + for (var i = 0; i < names.length; ++i) { + src += '

Hi

'; + } src += ''; var frame = document.createElement('iframe'); frame.src = 'data:text/html,' + src; @@ -346,18 +344,10 @@ var FontLoader = { 'width: 10px; height: 10px;' + 'position: absolute; top: 0px; left: 0px;'); document.body.appendChild(frame); - - frame.onload = function() { - Objects.resolve(fontObj.loadedName); - } /** Hack end */ } }; -if (!isWorker) { - FontLoader.setup(); -} - var UnicodeRanges = [ { 'begin': 0x0000, 'end': 0x007F }, // Basic Latin { 'begin': 0x0080, 'end': 0x00FF }, // Latin-1 Supplement @@ -514,6 +504,9 @@ var FontShape = (function FontShape() { this.$name2 = 'px "' + name + '", "'; this.supported = Object.keys(this.encoding).length != 0; + + // Set the loading flag. Gets set to false in FontLoader.bind(). + this.loading = true; }; function int16(bytes) { diff --git a/pdf.js b/pdf.js index 77c57e528..bd9a9f7b2 100644 --- a/pdf.js +++ b/pdf.js @@ -3348,7 +3348,8 @@ var Page = (function() { var self = this; this.IRQueue = IRQueue; - var displayContinuation = function() { + var displayContinuation = function() { + console.log('--display--'); // Always defer call to display() to work around bug in // Firefox error reporting from XHR callbacks. setTimeout(function() { @@ -3391,18 +3392,16 @@ var Page = (function() { }, ensureFonts: function(fonts, callback) { + console.log('--ensureFonts--'); + // Convert the font names to the corresponding font obj. + for (var i = 0; i < fonts.length; i++) { + fonts[i] = Objects.get(fonts[i], true); + } + + // Load all the fonts FontLoader.bind( fonts, function(fontObjs) { - // Rebuild the FontsMap. This is emulating the behavior of the main - // thread. - if (fontObjs) { - // Replace the FontsMap hash with the fontObjs. - for (var i = 0; i < fontObjs.length; i++) { - FontsMap[fontObjs[i].loadedName] = {fontObj: fontObjs[i]}; - } - } - this.stats.fonts = Date.now(); callback.call(this); @@ -4174,7 +4173,7 @@ var PartialEvaluator = (function() { fnArray.push("dependency"); argsArray.push(depList); for (var i = 0; i < depList.length; i++) { - dependency.push(depList); + dependency.push(depList[i]); } } @@ -4353,7 +4352,7 @@ var PartialEvaluator = (function() { if (font.translated) { // keep track of each font we translated so the caller can // load them asynchronously before calling display on a page - var loadedName = "font_" + getIRQueue + + (FontLoadedCounter++); + var loadedName = "font_" + uniquePrefix + (FontLoadedCounter++); font.translated.properties.loadedName = loadedName; FontsMap[loadedName] = font; diff --git a/worker.js b/worker.js index 8148ff3f1..9364a8278 100644 --- a/worker.js +++ b/worker.js @@ -89,9 +89,13 @@ var Objects = { } }, - get: function(objId) { + /** + * If `ignoreResolve` is true, this function doesn't test if the object + * is resolved when getting the object's data. + */ + get: function(objId, ignoreResolve) { var obj = this.hash[objId]; - if (!obj || !obj.isResolved) { + if (!ignoreResolve && (!obj || !obj.isResolved)) { throw "Requesting object that isn't resolved yet " + objId; } return obj.data; @@ -112,6 +116,7 @@ var Promise = (function() { if (data != null) { this.isResolved = true; this.$data = data; + this.hasData = true; } else { this.isResolved = false; this.$data = EMPTY_PROMISE; @@ -219,7 +224,11 @@ var WorkerPDFDoc = (function() { var pageNum = data.pageNum; var page = this.pageCache[pageNum]; + // DepFonts are all fonts are required to render the page. `fontsToLoad` + // are all the fonts that are required to render the page AND that + // aren't loaded on the page yet. var depFonts = data.depFonts; + var fontsToLoad = []; function checkFontData() { // Check if all fontObjs have been processed. If not, shedule a @@ -227,14 +236,18 @@ var WorkerPDFDoc = (function() { // the next fonts. for (var i = 0; i < depFonts.length; i++) { var fontName = depFonts[i]; - var fontObj = Objects.get(fontName); + var fontObj = Objects.getPromise(fontName); if (!fontObj.hasData) { + console.log('need to wait for fontData', fontName); fontObj.onData(checkFontData); + return; + } else if (!fontObj.isResolved) { + fontsToLoad.push(fontName); } } // At this point, all font data ia loaded. Start the actuall rendering. - page.startRenderingFromIRQueue(data.IRQueue, depFonts); + page.startRenderingFromIRQueue(data.IRQueue, fontsToLoad); } checkFontData(); @@ -265,12 +278,14 @@ var WorkerPDFDoc = (function() { fontHandler.on('font_ready', function(data) { var objId = data[0]; var fontObj = new FontShape(data[1]); + + console.log('got fontData', objId); + // If there is no string, then there is nothing to attach to the DOM. if (!fontObj.str) { Objects.resolve(objId, fontObj); } else { Objects.setData(objId, fontObj); - FontLoader.bind(fontObj); } });