Add dependency management for loading images that causes the execution to halt if the dependency isn't satisfied during executing time

This commit is contained in:
Julian Viereck 2011-09-07 19:50:05 -07:00
parent e7b636dba4
commit 7e3bbccaae
2 changed files with 76 additions and 35 deletions

57
pdf.js
View File

@ -861,13 +861,15 @@ var PredictorStream = (function() {
var JpegStreamIR = (function() {
function JpegStreamIR(objId, IR) {
var src = IR;
var src = 'data:image/jpeg;base64,' + window.btoa(IR);
// create DOM image
var img = new Image();
img.onload = (function() {
this.loaded = true;
Objects[objId] = this;
Objects.resolve(objId, this);
if (this.onLoad)
this.onLoad();
}).bind(this);
@ -925,7 +927,7 @@ var JpegStream = (function() {
if (isYcckImage(bytes))
bytes = fixYcckImage(bytes);
this.src = 'data:image/jpeg;base64,' + window.btoa(bytesToString(bytes));
this.src = bytesToString(bytes);
}
constructor.prototype = {
@ -3453,8 +3455,16 @@ var Page = (function() {
width: this.width,
height: this.height,
rotate: this.rotate });
gfx.executeIRQueue(this.IRQueue);
gfx.endDrawing();
var startIdx = 0;
var length = this.IRQueue.fnArray.length;
var IRQueue = this.IRQueue;
function next() {
console.log("next executeIRQueue", startIdx, length);
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next);
}
next();
},
rotatePoint: function(x, y) {
var rotate = this.rotate;
@ -4285,7 +4295,11 @@ var PartialEvaluator = (function() {
IR: image.getIR()
});
// TODO: Place dependency note in IR queue.
// Add the dependency on the image object.
fnArray.push("dependency");
argsArray.push([ objId ]);
// The normal fn.
fn = 'paintJpegXObject';
args = [ objId, w, h ];
} else {
@ -4864,12 +4878,35 @@ var CanvasGraphics = (function() {
this.ctx.scale(cw / mediaBox.width, ch / mediaBox.height);
},
executeIRQueue: function(codeIR) {
executeIRQueue: function(codeIR, startIdx, continueCallback) {
var argsArray = codeIR.argsArray;
var fnArray = codeIR.fnArray;
for (var i = 0, length = argsArray.length; i < length; i++) {
this[fnArray[i]].apply(this, argsArray[i]);
var i = startIdx || 0;
var length = argsArray.length;
for (i; i < length; i++) {
if (fnArray[i] !== "dependency") {
this[fnArray[i]].apply(this, argsArray[i]);
} else {
var deps = argsArray[i];
for (var n = 0; n < deps.length; n++) {
var depObjId = deps[n];
var promise;
if (!Objects[depObjId]) {
promise = Objects[depObjId] = new Promise();
} else {
promise = Objects[depObjId];
}
// If the promise isn't resolved yet, add the continueCallback
// to the promise and bail out.
if (!promise.isResolved) {
console.log("Unresolved object: " + depObjId);
promise.then(continueCallback);
return i;
}
}
}
}
return i;
},
endDrawing: function() {
@ -5367,7 +5404,7 @@ var CanvasGraphics = (function() {
},
paintJpegXObject: function(objId, w, h) {
var image = Objects[objId];
var image = Objects[objId].data;
if (!image) {
error("Dependent image isn't ready yet");
}

View File

@ -51,12 +51,27 @@ var WorkerPage = (function() {
})();
// This holds a list of objects the IR queue depends on.
var Objects = {};
var Objects = {
resolve: function(objId, data) {
// In case there is a promise already on this object, just resolve it.
if (Objects[objId] instanceof Promise) {
Objects[objId].resolve(data);
} else {
Objects[objId] = new Promise(data);
}
}
};
var Promise = (function() {
function Promise(name) {
this.name = name;
this.isResolved = false;
function Promise(data) {
// If you build a promise and pass in some data it's already resolved.
if (data != null) {
this.isResolved = true;
this.data = data;
} else {
this.isResolved = false;
}
this.callbacks = [];
};
Promise.prototype = {
@ -83,6 +98,7 @@ var Promise = (function() {
}
}
}
return Promise;
})();
var WorkerPDFDoc = (function() {
@ -95,7 +111,7 @@ var WorkerPDFDoc = (function() {
this.pageCache = [];
var useWorker = true;
var useWorker = false;
if (useWorker) {
var worker = new Worker("../worker/boot.js");
@ -125,29 +141,17 @@ var WorkerPDFDoc = (function() {
font.file.end - font.file.start, fontFileDict);
font.file = new FlateStream(fontFile);
}
var imageLoadingDone = function() {
var timeStart = new Date();
console.log("startRenderingFromPreCompilation:", "numberOfFonts", fonts.length);
page.startRenderingFromIRQueue(data.IRQueue, data.fonts, data.images);
console.log("RenderingTime", (new Date()) - timeStart);
}
var images = data.images;
if (images.length != 0) {
// Generate JpegStreams based on IR information and start rendering
// once the compilation is done.
var loader = new ImagesLoader();
loader.onLoad = imageLoadingDone;
for (var i = 0; i < images.length; i++) {
var image = images[i];
var stream = new JpegStreamIR(image.id, image.IR);
loader.bind(stream);
}
} else {
imageLoadingDone();
for (var i = 0; i < images.length; i++) {
var image = images[i];
var stream = new JpegStreamIR(image.id, image.IR);
}
var timeStart = new Date();
console.log("startRenderingFromPreCompilation:", "numberOfFonts", fonts.length);
page.startRenderingFromIRQueue(data.IRQueue, data.fonts, data.images);
console.log("RenderingTime", (new Date()) - timeStart);
}, this);
if (!useWorker) {